
















               ****************************************
               *                                      *
               * GameBasic User's Guide - Version 1.1 *
               *                                      *
               ****************************************





_________________________________________________________________
_________________________________________________________________

     All rights reserved.  Basic and QBasic are registered
     trademarks of Microsoft Corp. Commercial games and other
     products named in this document are the trademarks of their
     respective owners and are used in an editorial fashion only,
     to the benefit of their respective trademark owners, with no
     intention of infringement of the trademarks.

               Copyright  (c) 1994 Michael R. Watts
_________________________________________________________________
_________________________________________________________________








                         Table of Contents
                         _________________



      1:  Welcome to GameBasic.
        1.1   What is GameBasic?
        1.2   System Requirements
        1.3   Installing GameBasic
        1.4   How do you make games with GameBasic?

      2: Files and Directories

      3: QBasic Programming Environment.
        3.1       Introduction
        3.2       Starting QBasic
        3.3       QBasic Programming Environment - a TOUR
        3.3.1           FILE - OPEN Option
        3.3.2           EDITING a Basic program
        3.3.2.1               Entering text with
                              Insert ON/InsertOFF
        3.3.2.2               Creating blank program lines
        3.3.2.3               Deleting characters/whole lines
        3.3.2.4               Moving/Copying
                                    /Deleting blocks of lines
        3.3.3           FILE - SAVE AS Option
        3.3.4           FILE - SAVE Option
        3.3.5           FILE - NEW  Option
        3.3.6           RUN  - START Option
        3.3.7           EXITING QBasic
        3.4       OTHER Qbasic Options/HELP


      4: Learning Basic programming.
        4.1      Flowcharting
        4.2      Variables in Basic
        4.2.1              Numeric Variables
        4.2.2              Using variables in calculations
        4.2.3              Alphabetic (STRING)  variables
                 Basic commands
        4.3                - CLS (Clear screen)
        4.4                - INPUT
        4.5                - PRINT
        4.6                - LOCATE
        4.7                - IF . . . THEN . . . ELSE
        4.8                - GOSUB
        4.9                - DO WHILE ....   LOOP
        4.10              - FOR .....  NEXT
        4.11              - CALL
                  Basic Arrays
        4.12              - DIM
        4.13              - REDIM
        4.14              - Debugging your program


      5: GameBasic Commands
        5.1      Introduction
        5.2      Gamebasic Base program
        5.3      CHAR$
        5.4      CALL DEFINECHAR
        5.5      CALL CREATE
        5.6      CALL MOVE
        5.7      INKEY
        5.8      CALL CONTROL
        5.9      CALL SHOOT
        5.10     CALL ACTIVE
        5.11     CALL CHECKHIT
        5.12     CALL DELETE
        5.13     CALL INFO
        5.14     CALL RAND
        5.15     CALL CHANGECHAR

      6: Additional Gamebasic Commands.
        6.1     CALL MOTION
        6.2     CALL GETANGLE
        6.3     CALL MUSIC
        6.4     CALL TEXTSCREEN
        6.5     CALL QUESTION
        6.6     CALL TRACK
        6.7     CALL COLOUR
        6.8     CALL DISTANCE
        6.9     CALL PAUSE
        6.10    CALL COLOURRESET
        6.11    CALL MOVEBACK
        6.12    CALL PIXELCOLOUR



      7:   Miscellaneous Gamebasic Features.
        7.1      gb.screen
        7.2      gb.slowdown
        7.3      Key repeatamatic rate
        7.4      Split-screen feature
        7.5      Basic TIMER



APPENDIX A:    INKEY VALUES
APPENDIX B:    GAMEBASIC ROUTINES SUMMARY
APPENDIX C:    QBASIC PF KEYS


**************************

1.   Welcome to GameBasic.

**************************

________________________

1.1   What is GameBasic?
________________________

     GameBasic is a program which enables students to create
     their own exciting animated computer games incorporating
     both sound and colour, using very simple commands in Basic.

     The objective of GameBasic is to make it FUN to learn
     computers and Basic programming, to de-mystify computers and
     to provide a platform which will encourage an enthusiasm for
     further computer studies, in this way preparing the student
     for the new work-place in which computer knowledge is
     essential.

     With GameBasic, students can develop their own versions of
     games like Space nvaders, HackMan, Racquet-ball, Question
     and Answer games with animation, and two-player keyboard
     games like Tank Battle. Examples of these games written in
     GameBasic are provided on the program disk (see Program
     GBDEMO.BAS).

     This User Guide uses simple language to explain to students
     the basic issues of PC file structures, the QBasic
     programming environment, Basic programming, Programming
     'Style' and how to use the GameBasic routines to develop
     their own games. The manual is supported throughout by Basic
     program examples and the development of one of the demo
     games is explained step-by-step with program examples.

__________________________

1.2    System Requirements.
__________________________

  To run GameBasic you must have the following:

     a)    QBasic   (QBasic comes with DOS versions 5 and higher
                    and will be ound in your DOS directory).

     b)    a 386 computer or better.  GameBasic will run on 286
                  computers, but your games will be faster if
                    you run GameBasic on a 386 machine or

                   better.

     c)   VGA monitor

     d)   Hard disk drive with 2.0 megabytes of free space.

__________________________

1.3. Installing GameBasic.
__________________________

     1. Copy all the files contained in this demonstration
     version of GameBasic into a new directory
     (eg: C:\GAMEBASI )

     2. After you have copied the files, to start QBasic make
     sure that your DOS Prompt is pointing to the directory
     containing the installed GameBasic files, then type QBASIC
     and press ENTER.

     3. Once you have QBasic started, press the keys ALT then F
     then alphabetic O to bring up the open-files menu, use the
     Tab key to move the highlight bar into the files window,
     then use the direction keys (<- -> etc) to highlight file
     GBDEMO.BAS then press the enter key. After the demo program
     has loaded, press F5 to run it. What you will see are a
     collection of games that have been written in GameBasic to
     demonstrate its power and ease-of-use.

     NOTE: If you are running the demonstration version of
     GameBasic, run program GBDEMO.EXE from the DOS prompt to
     play the demonstration games. Code for these games is
     provided in file GBCODE.TXT.

     NOTE: Just in case GameBasic files become corrupted, you
     should make one copy of the files you received and store it
     in a safe place. You can then use this copy to re-install
     GameBasic if the original disk is un-useable for any reason.

___________________________________________

1.4   How do you make games with GameBasic?
___________________________________________

     1. Have you ever heard of the word "SPRITE"?  The dictionary
     says that a SPRITE is an elf, pixie, fairy or goblin. It
     could even be called a SPIRIT - an image that mysteriously
     appears, moves around, and then disappears, just like
     a ghost.  Scary stuff!  In computer-talk, we use the word
     SPRITE to mean exactly the same thing - an image or
     character that we show on the computer screen, make it move
     around and then, maybe, make it disappear. The only
     difference is that in computers, Sprites are not mysterious
     - they're controlled by a program. A program that you will
     be writing very soon using GameBasic!

     2. GameBasic makes it very easy for you to create your own
     special multi- coloured characters. For each character you
     want to create, you just fill-out a grid of 16 horizontal
     dots by 12 vertical dots (a block of 16 x 12) and tell the
     computer which colour you want each dot to be shown as. The
     combination of all the dots make up your special character.

     3. The following is an example of how you would define a
     Cannon character in GameBasic (actually, this is the Cannon
     definition that is used in the ALIEN INVADERS game in
     GBDEMO.BAS):

     char$(1, 1) = "                "
     char$(1, 2) = "                "
     char$(1, 3) = "
     char$(1, 4) = "                "
     char$(1, 5) = "        7       "
     char$(1, 6) = "        7       "
     char$(1, 7) = "       373      "
     char$(1, 8) = " 33333333333333 "
     char$(1, 9) = "33  3 3 3 3 3 33"
     char$(1,10) = "3333333333333333"
     char$(1,11) = "  6 6      6 6  "
     char$(1,12) = "   6        6   "

     4. Now, just look at all the "3"'s. The number 3 represents
     the colour cyan (a kind of light bluey-green); number 7 is
     white and 6 is brown. Since the screen background will be
     black, all the spaces you see here will show up as black.
     What you will see when the Sprite is displayed will be the
     cyan body of the Cannon, the white barrel (pointing up) and
     the brown wheels. So you can see how easy it is to create
     your own special characters in GameBasic.

     5. In GameBasic, you might create a Spaceship character, a
     scary Alien character or even a big green monster - you can
     create up to 20 different characters to be used in your
     program in GameBasic. One character might be an evil
     invading Space Alien, dropping down from the skies to
     gobble-up your town! Each character you create has to be
     given a character number - so let's call this Alien
     Character Number 1. Now, in your program you want to
     have not one Alien dropping from the skies, but 30 in 3 rows
     of 10. Each Alien you create to appear on the screen would
     use the same Character Number (in this case, character 1)
     but would be identified as a unique Sprite Number. In
     GameBasic, you can have up to 90 different sprites in each
     game. In our demo program, we create 30 Aliens with Sprite
     Numbers from 10 to 39 (yes, that does equal 30!) but each
     Sprite uses character Number 1 for it's definition, so they
     all appear the same.

  6. At the top of your program you will use the GameBasic
     DEFINECHAR command to define all your special characters.
     You will then use other GameBasic commands to control what
     happens in your program. These commands are very powerful,
     and save you a lot of time in programming thus making your
     program much faster to write and much easier to understand
     and change since there will be very few Basic statements in
     it.
  7. The next command after DEFINECHAR that you're likely to use
     is the CREATE command. This command assigns a "sprite
     number" to the sprite, tells GameBasic which special
     character to display the sprite as, and puts it on the
     screen at the row and column you specify. The CREATE command
     also tells GameBasic what speed and in which direction the
     sprite should move, as well as what to do with the Sprite
     when it hits a screen border - ie the top,bottom or either
     side of the screen. When it hits a screen border, you have
     the following options:

     7.1  Sometimes, you might want to have the Sprite
          wrap-around the screen. This means that when the Sprite
          gets to one of the edges, it re-appears on the opposite
          edge.  In other words, if the Alien has got to the left
          edge of the screen, it would re-appear on the right
          edge if we had said Wrap.

     7.2  Another option is to delete the Sprite. This is useful
          where we have fired a missile, for example, and it has
          reached the top of the screen without hitting any of
          those pesky Aliens.

     7.3   Yet another option is to leave the Sprite at the edge
          of the screen. This is useful where the Sprite is one
          that is controlled by the keyboard (more about this
          later) such as a Cannon. Here, we don't want the Cannon
          to get deleted when it reaches the edge, nor do we want
          it to wrap-around the screen - we want it to stay where
          it is until the player moves it back.

     7.4  A final option is to make the Sprite "Bounce" off the
          sides, top or bottom, just like a ball.

  8. You use GameBasic's CONTROL command to define which Sprite
     number should be controlled by the keyboard, whether it can
     move up, down, left or right, which keys will move it in a
     particular direction and,  when a "Fire" key is pressed,
     what character should be fired (maybe a missile you've
     defined) and in which direction. This is a very powerful
     command, saving you a lot of programming time.

  9. GameBasic's CHECKHIT command is used to check if one Sprite
     has hit another one, or one of a range of Sprites. For
     example, one CHECKHIT instruction could be used to see if a
     Missile sprite has hit any of our 30 invading Aliens! If it
     had hit one, then our program could be coded such that the
     Alien disintegrates or even changes colour....

  10. Finally, one really useful GameBasic command is the SHOOT
     command. Using SHOOT, your program can literally shoot a
     specific Character from one Sprite to another Sprite at a
     given speed. This is used in some of the demonstration games
     where the Aliens are firing FireBalls directly at the Cannon
     - they seem to know where the Cannon is every time! This is
     done with the SHOOT command. GameBasic handles all the angle
     calculations for you, so you don't have to worry about
     complicated programming stuff.

  11. The exciting feature of GameBasic is that once you've
     defined all your special characters and you've told
     GameBasic where to put the characters on the computer
     screen, in which direction they should move and how fast,
     GAMEBASIC WILL DO ALL THE MOVEMENT FOR YOU. You don't have
     to worry about all the complicated programming involved in
     moving Sprites  - you can concentrate on making a computer
     game that your friends will be amazed at!  Maybe you'll beat
     them this time?

  12.  This is just a short explanation of some of the routines
     included in GameBasic - these and all the other GameBasic
     subroutines are fully explained in Chapters 5 and 6  -
     GameBasic Commands.

  I'm sure you can see that with the power of the routines that
have been created in GameBasic, you will be able to develop very
sophisticated computer games with as little programming as
necessary.


__________________________

2.  FILES AND DIRECTORIES
__________________________

    1. Before we start to explain the QBasic Programming
     Environment in detail, which I know you're eager to learn,
     we have to take some time to discuss some general computer
     issues.

    2.  Computers process data!   Data can mean files of PROGRAM
     INSTRUCTIONS, which tell the computer exactly what to do, or
     files of INFORMATION like "Customer Names and Addresses" or
     "Highest Scores" in a Computer Game on which the programs
     act. The term FILE means a collection of similar
     information, like a file of Employee Names or a file of
     Baseball Cards.

     We choose a name for each file we create in our computer;
     the name can be up to 8 characters long and usually has a
     dot followed by three characters added to the end. For
     example, BASEBALL.DAT would be a valid file name and might
     contain information on each of the cards in a BaseBall
     Collection such as Player's Name, Team, Year, Date Bought,
     Price, Home Runs etc.... Many of the files in a computer
     system, however, are program files which already have a name
     and came with the Program that was installed. Normally,
     these files contain funny characters that don't make any
     sense (if you were to look at them) - however, our computer
     understands them because they contain coded program
     instructions.

   3. Files in a computer are normally stored on a disk. Each
     disk drive is given a drive letter from A to Z so we can
     tell the computer  which disk drive we want it to read or
     write. There can be a number of different disk drives in a
     computer. Just take a look at your computer now. You may see
     a slot where a large 5 1/2" floppy disk goes - this is
     probably called your "A" DRIVE. If you also have a smaller
     disk drive that takes the 3 1/2" disks, it's probably called
     your "B" DRIVE. But there is one more disk drive that you
     can't see, although you can probably see its light come on
     when it's being read or written - this is your computer's
     internal or hard drive (since its not a floppy). It is
     larger than either of the two floppy drives and can hold a
     lot more information on it. This internal hard drive is
     normally called your "C" drive, but hard drives can also
     have other drive letters like "D", "E" etc... All this means
     is that the large hard disk inside your computer has been
     sub-divided into smaller drives. It hasn't been physically
     cut up; just imaginary - like drawing lines on a sheet of
     paper and labelling the areas "C", "D" etc....
   4.  So why all this talk about disk drives? Well, computer
     files are not only assigned a name, but they are also
     assigned to a disk drive by putting the drive letter and a
     colon in front of the file name. If our BASEBALL.DAT file
     was on our "C" internal hard drive, we could refer to it
     with the name C:BASEBALL.DAT this would tell DOS (the
     operating system that handles all our file and program
     processing) that the file can be found on the "C" internal
     hard disk drive with the name BASEBALL.DAT

  5.  Now, if all our different programs that we have in our
     computer were on the same disk drive, we'd have quite a
     mess. There would be no easy way to tell which files belong
     to our Game, which files belong to the program which does
     Dad's Tax Return, which files belong to Mum's CookBook Card
     system and so on. They'd all be jumbled up together - a real
     mess.

  6. To get over this problem, we store all files for a
     specific program in their own DIRECTORY, to which we give a
     a  label saying COOKBOOK RECIPES, another file folder might
     have a label saying BASEBALL CARDS and so on. Now in our
     computer we  could keep all Mum's recipes in the COOKBOOK
     file-folder, and all our BASEBALL Cards in the BASEBALL file
     folder. This keeps all similar files together, and stops
     them getting mixed up (just in case Mum might confuse one of
     our Baseball cards with one of her recipes).

     Both these file folders (or DIRECTORIES) could be on the
     same disk drive.  We can picture this as follows:

                              DISK DRIVE C

                         _________|_______
                         |                |
                         |                |
                         |                |
                       BBALL            CBOOK <-----DIRECTORIES
                         |                |
                         |                |
                       baseball.dat    recipes.doc<-----FILES
                       baseball.prg    cookbk.prg
                         etc..           etc..

   7. When we want to tell DOS (our computer's operating system)
where our BASEBALL.DAT file is, we have to tell DOS that it's in
the BBALL directory under the name of BASEBALL.DAT. The character
string C:\BBALL\BASEBALL.DAT does this.

    NOTE that it doesn't make any difference if you type your
file or directory names in capital letters or small letters -
they're both the same as far as DOS is concerned.

____________________________________

3.    QBASIC PROGRAMMING ENVIRONMENT
____________________________________


3.1  Introduction
_________________

      What is the QBasic Programming environment, and why do you
     have to learn it first?

      When you program in QBasic, you will be creating a file
     containing Basic Program instructions that tell the computer
     exactly what to do. This file will contain a number of
     lines, depending upon the size of your program. When you
     tell Basic to RUN your program, it will process each line in
     your program in sequence until it gets to the end or an
     instruction that says END or STOP.

      The QBasic Programming Environment is a collection of
     screens that let you create, change and run your Basic
     Programs. Using this environment, you can create a new Basic
     program, save a program to disk giving it it's own name,
     change a program you previously created, run programs, print
     out your program listings and so on.

  3.2  Starting QBasic.
  _____________________

     1.   In the previous chapter we discussed FILES and
     DIRECTORIES.  What does all this have to do with learning
     the QBasic Programming Environment?

     Well, the first thing you're going to have to do NOW is to
     start-up the program that runs this QBasic Programming
     Environment. This is called QBASIC.EXE and should be found
     on the disk drive and in the directory containing your DOS
     operating system (probably C:\DOS ).  If you're not sure
     where this drive and directory is, you may need to ask your
     parent or a  computer-knowledgeable person.

     2.  After you've turned the computer on, it will start
     loading in its operating system from the hard drive and then
     display what we call the DOS PROMPT. This will normally look
     like "C:\>_" or "C:\DOS>_"  The underscore character will be
     flashing. This is the "Cursor" position, where anything you
     enter from the keyboard will be displayed on the screen.

     3.   Now you have to change the DOS Prompt to point to the
     directory where you installed the GameBasic files that came
     on the Program disk.  First, if the drive containing your
     installed GameBasic files is not the same as the drive your
     DOS prompt is currently pointing to (ie the C in  C:\DOS ),
     then you will have to change the drive. Do this by typing
     "x:", without the quotes, where x is the letter of the drive
     containing your installed GameBasic files.

          Having done the above, if you needed to, now type
     "CD  \  xxxxxxxx", again  without the quotes, where xxxxxxxx
     is the directory name that contains your GameBasic files,
     and press the Enter key.

          Finally, to start the QBasic program, type QBASIC and
     press enter.  If you get an error message during the above,
     then either
           a) You typed in a wrong directory name or character
              (redo from the start)

        or b) Your DOS directory is not included in your
               AUTOEXEC.BAT file's PATH statement. (You'll have
               to get someone to add it for you)

        or c) You don't have the QBASIC.EXE program on your
               computer. (you will not be able to run GameBasic
               without QBASIC.EXE)

     4.   After the computer loads the QBASIC program into its
          memory, you  should see the following on your screen.
_________________________________________________________________
| File  Edit  View  Search  Run  Debug  Options            Help |
|_________________________________Untitled______________________|
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|              ________________________________________         |
|             |                                         |       |
|             |     Welcome to MS-DOS QBasic            |       |
|             |                                         |       |
|             |Copyright (C) Microsoft Corporation      |       |
|             |      All rights reserved.               |       |
|             |                                         |       |
|             |< Press Enter to see the Survival Guide >|       |
|             _________________________________________ |       |
|             |< Press ESC to clear this dialog box >   |       |
|             |_________________________________________|       |
|                                                               |
|_______________________________________________________________|


          YOU ARE NOW IN QBASIC - CONGRATULATIONS!
_________________________________________________

3.3  The QBasic Programming Environment- a Tour.
_________________________________________________

HINT: IF AT ANY TIME WHILE IN THE QBASIC ENVIRONMENT YOU FIND
THAT THE COMPUTER DOESN'T SEEM TO BE RESPONDING TO THE KEYBOARD,
PRESS THE ESCAPE KEY A COUPLE OF TIMES TO RESET THE COMMAND BAR
AT THE TOP.

First, press the Esc key to clear the dialog box.

Now, look at the top of the screen. You'll see eight commands;
File, Edit, View, Search, Run, Debug, Options and Help.

By pressing the Alt key followed by the first character of an
Option (for example, Alt and F for the File option) each of the
options brings-up a menu of actions that you can chose from. Once
a menu is displayed, you can use the direction keys (<- -> etc) to
move the highlight bar to the action you want to take.

Try it now. Press Alt and F. You should now see a menu below the
File Option that looks like the following:

________________________________________________________________
| File  Edit  View  Search  Run  Debug  Options             Help|
|                                                               |
|____________________________Untitled___________________________|
|  | New       |                                                |
|  | Open...   |                                                |
|  | Save      |                                                |
|  | Save As.. |                                                |
|  |___________|                                                |
|  | Print.  . |                                                |
|  |___________|                                                |
|  | Exit      |                                                |
|  |___________|                                                |
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|                                                               |
|_______________________________________________________________|

          From this menu of choices, you can tell QBasic that you
          want to create a "N"ew program, "O"pen an existing
          Basic program, etc.... All you need to do when you see
          the choices to select an action is to press the
          capitalised letter of your choice.


We'll now take each option one at a time.


3.3.1.    FILE - OPEN option.
_____________________________

          With the File menu bar displayed, (ALT followed by F)
          press the key for the letter O.

          You will now see a window appear that shows you all the
          Basic program files that are stored in the directory
          that is shown just below File Name (for example,
          C:\GAMEBASE)

_________________________________________________________________
|  File  Edit  View  Search  Run  Debug  Options            Help|
|____________________________Untitled___________________________|
|   ___________________________ Open ___________________________|
|  |             _____________________________________________  |
|  | File Name: |*.BAS                                        | |
|  |            |_____________________________________________| |
|  | C:\GAMEBASE                                                |
|  |                     Files               Dirs/Drives        |
|  |   _____________________________________    _____________   |
|  |  | BAS01.BAS    BAS09.BAS  GAME02.BAS  |  | ..          |  |
|  |  | BAS02.BAS    BAS10.BAS    GAME03.BAS|  |[-A-]        |  |
|  |  | BAS03.BAS    BAS11.BAS    GAME04.BAS|  |[-B-]        |  |
|  |  | BAS04.BAS    BAS12.BAS    GAME05.BAS|  |[-C-]        |  |
|  |  | BAS05.BAS    BAS13.BAS    GAME06.BAS|  |   .         |  |
|  |  | BAS06.BAS    BAS14.BAS    GAME07.BAS|  |   .         |  |
|  |  | BAS07.BAS    GBBASE.BAS   GAME08.BAS|  |   .         |  |
|  |  | BAS08.BAS    GAME01.BAS   GAME09.BAS|  |             |  |
|  |  |_____________________________________|  |_____________|  |
|  _____________________________________________________________|
|                                                               |
|                                                               |
|_______________________________________________________________|

          To select a program file so that you can change it,
     press the Tab key to get the flashing cursor into the FILES
     area of the window (The Tab key looks like -->| ). Once the
     cursor is in this area, press the direction keys to move the
     highlighted area to the program file you want. For this
     example, move it so that it highlights the file named
     BAS01.BAS. Now press the Enter key.

Demo program BAS01.BAS

          QBasic will now go and read that file off the disk and
     display the program code in an edit window. You can now
     change the program; the next section will explain exactly
     how you do that.
__________________________________

3.3.2.    EDITING A BASIC PROGRAM.
__________________________________

          Now that you have a basic program displayed in the edit
window, you can move the cursor up, down, left and right (using
the direction keys) to the place in the program where you want to
make a change.

          Notice, as you do this, that the lines in your program
scroll up and down when you go past the top or bottom of the
screen. You can also use the Page Up and Page Down keys to move
up and down in your program page by page. The Home and End keys
take you to the beginning or end of the program line your cursor
is on currently.

          Now, a word about the QBasic editor and program
commands.

          Until you have an understanding of what the QBasic
programming commands are, you'll find it difficult to make
changes to a QBasic program file since QBasic has a "Smart"
editor. This means that each time you make a change to a program
line, if QBasic doesn't understand what you've entered (ie it is
not a valid program instruction) it will display an error
message. For this reason, the file BAS01 contains only Comment
records (ie records that have either the three letters REM (which
stands for Remarks) or a single quote ( ' ) at the beginning of
the line). To QBasic, all the text following a single quote (or
REM) is comments, not program instruction, so you won't get an
error message when you change any of these lines (as long as you
don't delete the REM or quote at the beginning of the line)


3.3.2.1   ENTERING TEXT WITH INSERT ON and INSERT OFF
_____________________________________________________

               OK, so now try and change some of the program
lines in BAS01.BAS

               Move the cursor to between the "IS" and "COMMENT"
words and type HELLO. See how the text HELLO is added to the
line, and all the text after the place where you inserted HELLO
is moved along! This is INSERT mode.

               Now, position the cursor to the character
immediately after the O in HELLO. Press the Enter key. Did you
see how the text after the cursor gets dropped down to a new
line!

               Now, if you type any characters into the line that
got dropped down and move the cursor up to the previous line
again you'll get an error message, since QBasic is saying that it
doesn't understand the command on the line that you just created
(the line doesn't start with REM or a quote, so it's NOT a
comment line now and QBasic thinks its a program command line).

               Press the Enter key to get back to the program and
now move the cursor back to the position immediately after the O
in HELLO again. Now press the Delete key. The previous line
should now have been moved back to where the cursor is.

               Now press the Insert key. This turns INSERT mode
off. Now go through the same steps again and watch the
differences. This is TYPEOVER mode - what you key in types over
what is under the cursor position; it doesn't move the following
text along.

               You can tell that you're in INSERT mode by the
shape of the cursor - the white line or box that is blinking on
the screen. In INSERT mode the cursor is a white blinking
underline; in type-over mode it's a large blinking white box.

               Got the idea?     If so, let's move on.


3.3.2.2   CREATING BLANK PROGRAM LINES.
_______________________________________

               You currently have INSERT mode turned off. Press
the Insert key again which will turn Insert mode ON again. Note
that the INSERT key acts as a "toggle", flipping between INSERT
ON and INSERT OFF each time it is pressed.


               Now move the cursor to the beginning of a line and
press Enter. The line will move down and  a blank line will be
shown where the cursor was. Keep pressing the Enter key, and you
get more blank lines. You can move the cursor up now and enter
new Basic commands in the blank lines you've just created
(remember to make the first characters either a quote ( ' ) or
REM, otherwise you'll get an error message again).


3.3.2.3   DELETING CHARACTERS or WHOLE LINES IN ONE STROKE.
___________________________________________________________

               You can delete characters to the right of the
cursor by pressing the DELETE key. You can also delete complete
lines.

        To do this, move the cursor to any program line.

     Now hold down the Ctrl key and press the Y key at the same
time. Watch the line where the cursor is on get deleted and all
following lines move up. This is one way you can delete program
lines you don't want any more.

          3.3.2.4   MOVING/COPYING/DELETING BLOCKS OF LINES.

               Quite often, you will have entered a number of
program lines somewhere in your program and later on, you'll want
to delete them or copy/move them to another place in your
program. This is how you do it. (You'll have to pay attention -
this is a little bit more difficult.)

                    A)   First, move the cursor to the first line
you want to copy, move or delete. Now, hold down the Shift key
and, while the Shift key is being pressed, move the cursor down
to the last line you want. (You can use the Page Down/Up and
arrow Direction keys to do this). Selected text will be
highlighted.
                    B)   Once you have selected all the text you
want, release the Shift key.

                    C)    Now, if you want to move the program
code from where it is and place it in a new location, (cut and
paste);
                         Holding the Shift key down, press the
Delete key to cut the program lines from their current location
(you will see them disappear), then move the cursor to where you
want to re-position the lines and, holding the Shift key down,
press the Insert key to paste the lines in the new position.

                    D)   If you want to leave the program lines
where they are but make a copy of them at another location:

                         Holding the CTRL key down, press the
Insert key to place a copy of the program lines into memory, then
move the cursor to the place where you want to copy the lines
and, holding the Shift key down, press the Insert key to copy the
lines to the new location. You can add additional copies of the
lines in new locations by moving the cursor to where you want the
lines and pressing the Shift/Insert keys again.

                    E)    If you want to Delete the highlighted
lines, simply press the Delete key.

               Practice this on program BAS01.BAS. It will save
you a lot of time later on when you are editing your programs.



3.3.3. FILE - SAVE AS Option.
____________________________

          As a safety feature, all GameBasic programs supplied on
the program disk have been installed in your directory as
READ-ONLY. This means that you can't make any changes to them.

          As you go through this User Guide you will be told to
retrieve these programs. It is suggested that immediately after
retrieving a program, you save it under a different name - use
the existing program name and add your initials to the end (for
example,  BAS01XX.BAS) where XX would be your initials.  Once you
have done this, then you can use your saved version to make
changes. Here is how you save a program under a different name:

               Use the SAVE AS option under the File menu (ALT +
F + A). In the File Name box, enter the new name for the program
and press the Enter key.

          When you save a program under a different name, Basic
doesn't re-name the existing program; it makes a copy of the
program, so your original program will still be there under its
original name.

          You will use the SAVE AS feature other times in your
program development. When you first start programming a new game,
you will have to retrieve the GameBasic Base program GBASE.BAS
and save it with the name you want to give to your new game. As
you develop your game, you should save the program as a different
name each time you get new features working in your game and
before you start developing new features. Then, if you "screw-up"
something (a technical term!) you can always go back to the
previous version that worked. It is suggested that you restrict
your game's name to 6 characters, then you can add a two digit
version number to the end (for example, ALIEN01.BAS, ALIEN02.BAS
etc..)




3.3.4.    FILE - SAVE Option.
____________________________

          Once you are happy with the changes you have made to
your program, you would normally RUN the program to see if it
gives you the results you wanted. If it did, then you would SAVE
the program for future use. But for now, we'll bypass the RUN
command and just SAVE the changes that we've made (assuming you
made a copy of program BAS01.BAS and added your initials to the
end as suggested in the previous section, and that that is the
program that you're now working with). If you are still working
with the original BAS01.BAS, you won't be able to save any
changes to it.

          To save your program, press the Alt, F, and S keys in
turn. As you press the keys, watch the top of the screen. You'll
notice that the Alt key highlights the choices bar. The F key
pulls down the Files menu and the S key selects the SAVE option.

          HINT: As you key in a new program, or make extensive
changes to an existing program, save the program after one or two
screens of input as a safety measure, just in case you lose power
before completing your input or your system "hangs-up" (yet
another technical term that relates to when your computer simply
"freezes" - accepting no input from the keyboard).



3.3.5      FILE - NEW Option.
______________________________

          When the File menu is displayed and you press the
letter N (for New), QBasic will set up a blank edit screen into
which you can start keying in Basic instructions for a new
program. When you have entered an instruction for one line, press
the Enter key and the cursor will jump to the start of the next
line. Any corrections or additions you want to make as you are
entering commands are done exactly the same way as described
above.

          However, there is one difference between entering a new
program and editing an existing program.

          When you have completed keying in your program and go
to save it (Alt, F, S), QBasic will ask you what name you want to
give your program. You've just written a new program, so QBasic
doesn't know what name to call it when you tell it to save the
program. In the window that pops up asking for the program name,
simply key in up to 8 characters for the program name. You can
key in less than 8 characters, but no more than 8. The name
should normally contain only alphabetic and numeric characters.


It is best to name a program for it's purpose so you can easily
identify it later when you're trying to find it among a list of
programs. In other words, ALIENINV is a better name for a game
program  than XPROG12. QBasic automatically gives your file the
extension of .BAS so if you looked at a list of files in the
directory you're currently in, you would see your program saved
as (for example) ALIENINV.BAS


3.3.6     RUN - START option.
_____________________________

          Let's run a real program now! (I can hear you saying
that it's about time).

Demo Program BAS02A.BAS

          We're going to get a program called BAS02A into the Edit
area then run it.

           First, press Alt, then F then O to select the File -
Open option. When the program selection screen comes up, move the
cursor to the Files area (use the Tab key;  - >|  ) and use the
direction keys to highlight program BAS02A.BAS Now press the Enter
key. BAS02A will be read from the disk and placed in the Edit area
of QBasic.   Here is the program:

               CLS
               PRINT "Hi there! So this is your first Basic
                    program?"
               END

          Can you make out what its going to do? If not, don't
worry, we'll explain everything about Basic commands in the next
chapter.

Let's run this program ! Press Alt, then R then S to select the
Run - Start option.

          The screen will now go black, and you'll see a message
printed in white at the top and a line that says "Press any key
to continue" at the bottom.  Our program has just run and come to
the end. It was a very simple program that just displayed a
message to the screen - but it WAS a program, even though it only
had three lines.

          Now, press any key. You will be passed back to the
QBasic Program Edit screen, with the BAS02A program showing again.
Change the text in the program between the quotes. Now press Alt,
R and S again. See how the message at the top of the screen has
changed! You've just made your first program change.

          Congratulations!

3.3.7     EXITING QBASIC.
_________________________


          To get out of QBasic and return to the DOS Prompt,
press ALT + F + X (eXit). If you have any unsaved program changes
outstanding, you will be asked by Basic if you want to save the
program before exiting.


3.4  OTHER QBASIC OPTIONS/QBASIC HELP
_____________________________________

          Before we finish our Tour of QBasic Programming
environment, you should notice that there are a number of other
options that can be selected from the top menu. To get an idea of
what they do and how to use them, please refer to the Basic Help
Option. You access this by pressing Alt, H and then selecting one
of the options presented. The documentation you will find in
Basic's Help is very comprehensive.


______________________________

4. LEARNING BASIC PROGRAMMING.
______________________________

     Don't listen to what other people tell you; programming is
not that difficult. Some people will tell you that you have to be
an expert at mathematics to be a programmer - that's not true!
You can be the class- dummy in mathematics and still be an expert
programmer - this author is an example. However, you do have to
think in a logical way because the computer follows your
instructions "to the letter". If you told it to jump in the river
(if computer's could do that), it would!


4.1  FLOWCHARTING.
__________________

          Now, what do we mean by "think in a logical way"?

          The computer performs mathematical calculations and
tests on numbers and makes decisions based on the results. That's
all it really does. The actions it is told to perform based on
the tests it does make up your program. We make decisions and
take action on those decisions every day of our lives. Let's take
an example. Suppose you were to draw out the decisions and
actions you make when you get up in the morning.


          First, you'd get up and get dressed then, if you were
hungry and there was food in the house, you'd have breakfast.
Finally, you'd leave the house for school or the office, taking
your rain-coat if it was raining. (Having a shower and brushing
your teeth are optional today!)

          If we were to draw out the decisions and actions that
you go through in what programmers call a flow-chart, it might
look something like the following:


Action: Get up.
Action: Get dressed
   V
   |                    Yes
Decision: Am I hungry? ----->
   |                        |
No |                        V               Yes
   V        Decision: Food in the house?---------->
   |                        |                      |
   |                    No  |                      |
   |                        V                      V
   |        Action: Drink water     Action:HaveBreakfast
   |                        |                      |
   |                        V                      V
   |---------------------<-----------------------<-
   V
   |                        Yes
Decision: Is It Raining? ------->
   |                             |
 No|                             |
   V                       Action: Take Raincoat
   |                             |
   |---------<--------------------
   |
Action: Leave House.

          Note that there can only be two outcomes from a
decision or test - either the condition is TRUE (it IS raining)
or it's FALSE (it's NOT raining).

          The decisions and actions in all computer programs can
be drawn in flow-chart diagrams similar to the one above. This is
a very good thing to do before you start entering your program
instructions into the computer - it gives you a high-level
diagram of what your program will do, so you can check the logic
for "logical" problems before you enter any code (Programmers
refer to program instructions as "code"). As an example, you
might have written "Is it sunny?" instead of "Is it raining".
Obviously, the action "Take Raincoat" is not appropriate if the
answer to "Is it sunny?" is YES. This is a logic error.

          Also, if you had said "Flush toilet" instead of "Take
Raincoat", this would probably be another logic error, unless
there was a very good reason you wanted to flush the toilet every
time it rained!

          As you write more programs, you'll find that you make
quite a few of these types of errors - your program will give you
some very funny results and you'll say "How could it be doing
that?" and eventually you'll trace the problem down to a silly
little error like one of the errors above, so it is strongly
recommended that you write a flow-chart of what your program will
be doing before you even start-up your computer.

4.2  VARIABLES IN BASIC.
________________________

          Having said this, we should now explain what a computer
program works with.

          A program performs operations on numbers and letters,
that's all. The data it works with (the numbers and letters) are
stored in separate areas inside the computer's memory. These
areas are called VARIABLES, and you give each variable its own
unique name.

          In Basic, variables can have up to 40 characters and
numbers in their name. They must start with an alphabetic
character and cannot have any spaces anywhere in the middle of
the name or any special characters like * - ( @ and so on.
Alphabetic characters used in variable names can be either upper-
case (capital letters) or lower-case (small letters).


4.2.1     NUMERIC VARIABLES
___________________________

          Again, let's take an example. Imagine that the two
figures we've drawn below are buckets; one we've called bucket A
and the other bucket B.

    ------
   |      |
   |   |  |    |         |         |
   |   |  V    |         |         |
A = 45 |       |         |         |
       |  45   |         |    0    |
        _______           _________

          A                   B

          The computer instruction  A = 45  will put the value of
45 into bucket A. (think of this instruction as saying "set A to
the value of 45").      Bucket B has zero in it.


    --------------------------
   |                          |
   |   |       |         |    |    |
   |   |       |         |    V    |
B = 66 |       |         |         |
       |  45   |         |    66   |
        _______           _________

          A                   B


          Now, if we were to say  B = 66 , (set bucket B equal to
66) then bucket A would still contain the value 45, but now
bucket B would not have zero; it would have 66 in it. If you were
to look into bucket B and open it up, you'd find number 66 lying
at the bottom. (That's meant to be a joke!)

          So now we have bucket A with 45 in it and bucket B with
66 in it instead of zero.

           -------------------
          |                   |
       |  |    |         |    |    |
       |  |    |         |    V    |
       |       |         |         |
       |  45   |         |    45   |
        _______           _________

          A                   B

          Now, if we were to write the instruction B = A, (set
bucket B equal to the value of bucket A), what do you think would
be in bucket B after the computer executes the command? (Remember
that when we said B = 66, the computer moved the value of 66 into
bucket B). Yes, Bucket B would contain 45, since you're telling
the computer to take the value laying in  bucket A and move it to
bucket B. Whatever was in bucket B before this command was
executed (the value of 66 in this example) would be lost forever,
gone for good, vanished away etc... (get the idea?). However,
when we moved the value of bucket A into bucket B, we didn't wipe
it out of bucket A. Bucket A still contains 45 - the same as
bucket B now. In other words, after this command has executed,
bucket B is the same as (or equals) bucket A.

Now, whenever your program uses bucket B, it would have the value
of 45 until a subsequent command in your program again changed
the contents of bucket B.

          If we now said   B = (A + 30) * 2 , what do you think
would be stored in bucket B after this command executes? (The
asterisk means Multiply). The answer is 150 since the computer
would look into bucket A and get the value of 45, then it would
add 30 to it to give 75, then multiply this last number by 2 to
give 150.

          So you see how the computer works. It stores its
numbers in buckets. Then, when a command uses that bucket, it
goes and extracts the number that's kept in the bucket and uses
it in the calculation. Pretty neat, huh?

          Finally, instead of calling the place where the
computer stores each number as a "bucket", let's call it a
"variable". Why the word VARIABLE? Well, it's because the value
that is stored in it can change from one command to the next as
the program is running. In other words, its contents are
variable.

          Whenever computer books talk about variables, they're
simply talking about these buckets where we keep values.

          As was mentioned above, we give our variables unique
names so we can tell the type of information we are storing in
them. This is quite handy, and helps us to read and understand
what our program is doing. Make your variable names meaningful so
that when you read through your program, you understand how each
variable is being used. As an example, if we were to set up a
variable to hold a score in a computer game, we'd probably call
the variable "score".  Too short a name (for example, "sc")
would not be very descriptive, and too long a name (even though
you can have up to 40 characters in your variables name) would be
too much typing each time you wanted to refer to the variable in
your program (ie "accumulated.score.this.game" )  as well as
being very error- prone (more about variable name errors in a
minute).

          Let's take an example to show what we've discussed
above.  Retrieve program BAS02.BAS now (Alt + F + O  then
highlight BAS02.BAS and hit enter).

The code (program instructions) looks like the following:


               CLS
               score = 0
               points.per.hit = 100

               ' print line 1
               PRINT "Score = "; score

               'print line 2
               score = points.per.hit
               PRINT "Score now equals "; score

               'print line 3
               score = score + points.per.hit
               PRINT "Score has been incremented to "; score

               'print line 4
               score = score + (points.per.hit * 2)
               PRINT "Score is now "; score
               END



          Run the program and see what it prints out on the
screen. (Basic runs your program by starting at the top and
executing each instruction in sequence until it gets to an END or
STOP instruction).

          When the program gets to the first PRINT instruction,
the value of the variable (bucket) called 'score' is zero (that's
what we set it to at the top of the program). The first printed
line will say

                Score = 0

          Next, we set the variable named score equal to the
value contained in variable points.per.hit (which is 100), so the
next print line will say

                Score now equals 100

          The next instruction takes the value that is currently
in the variable (bucket) called score (which is 100), adds the
value that's currently in the variable named points.per.hit
(which is 100 also) and places the result of the addition (200)
back in the variable named score, so the next print line says

               Score has been incremented to 200

          Finally, the next instruction multiplies the value
currently in points.per.hit by 2, adds the result of this
multiplication (which is 100 * 2  =  200) to the value currently
in the variable called score (which is 200) and places the result
of this whole calculation back in the variable score. So the last
print line will say

               Score is now 400

          Get the idea?  Try making some changes to the
calculations and see the different results you get!

     HINT: WHEN YOU'RE TYPING IN YOUR PROGRAM INSTRUCTIONS, BE
VERY CAREFUL TO MAKE SURE THAT YOU SPELL YOUR VARIABLE NAMES
CONSISTENTLY.

          Let's look at one type of error that can be made with
mis-spelled variable names.  Change the second PRINT line in
program BAS02.BAS that says

                    PRINT "Score now equals "; score
          to say    PRINT "Score now equals "; scire


          Run the program again. On the second line it prints
out, it will now print

                    Score now equals 0

          We deliberately mis-spelled the variable "score" above
as "scire". When the basic program comes to execute this program
ine, it won't know that you really meant to type "score" . Since
asic hasn't come across the variable "scire" before it gets to is

print line, it will assume that "scire" is a new variable and set
t up with a value of zero (the initial value for numeric
ariables).  Instead of the program printing

                               Score now equals 100
          it will print        Score now equals 0


          Sometimes the error you have made in a variable's name
is not obvious and doesn't come springing out at you, especially
hen there is a lot of program code between the place where the
rror was made and the last place the variable was correctly amed.
ou can waste quite a lot of time tracking down a spelling error -
so TAKE CARE!


4.2.2     USING VARIABLES IN CALCULATIONS.
__________________________________________


          In Basic, you can perform any arithmetic calculation
using any number of variables. The operations you can perform
include addition (+), subtraction   (-), division (/) and
multiplication (*). Note that multiplication uses the * character
rather than the normal X (since X is an alphabetic character and
could be mistaken by Basic for a variable name). Calculations
should  be bracketed for clarity - the number of left and right
brackets have to be equal.


          There are correctly formatted calculations (although
they're not very descriptive variable names):
                    abc = ( (aa + bb) * gg ) / xx
                    x = y * (a - b) / 100.34

          This next line would be invalid because there is one
more left-bracket than right brackets:
                     x = ( (d - 40) * 2.67

          So now you know you that the computer stores numbers in
buckets which we call "variables" and we give them names to refer
to them by, so let's move on shall we?



4.2.3     ALPHABETIC VARIABLES
______________________________

          There's one other type of information that computers
store as well. Can you guess what it is? The answer is Alphabetic
information or text , like your name or your address. This type
of information is not like numeric information because you can't
do mathematical calculations on it, but it does get stored in the
computer's memory in nearly the same way.

          If we wanted to store your name in a text variable
(which is called a STRING variable in Basic because it's a string
of characters),   we would say

                    Name$ = "John Doe"

          There are two differences between this string variable
and a numeric variable (like A = 30).  First, the variable name
has a $ (dollar sign) after it. Think of this sign as an S (for
STRING) with a line through it rather than a dollar sign. Basic
stores string information in a different way internally than it
stores numeric information - the $ sign tells Basic that the
variable is a string variable and will hold alphabetic characters
rather than a number. Secondly, the value we want to store in
this variable is enclosed in quotes. If we left the quotes off,
Basic would get confused and think that John and Doe are the
names of numeric variables.

          So remember: for string variables - dollar sign at the
end of the variable name and quotes around the value.


          One last word about string variables. You'll remember
that we said that you can't do arithmetic on string variables -
well that's not quite true; you can add them together.


Demo Program BAS03.BAS

          Load program BAS03.BAS and look at it. This is a
GameBasic program.

          (All programs starting with BAS or GAME include only
those GameBasic routines neccessary to support the example being
taught. If you change them to call other GameBasic routines you
will get an error. Program GBASE.BAS includes ALL GameBasic
routines).

          You will notice two program lines at the top enclosed
between two lines of asterisks. These are GameBasic instructions
and must NOT be changed. For the purposes of this example, your
program code starts after the line of exclamation points ( !!!!
).  Don't get confused by the DO WHILE and LOCATE instructions;
we'll cover those in a minute.

                    first.name$ = "John"
                    last.name$ = "Doe"
                    defender.name$ =  first.name$ + last.name$
                    score = 0
                    points.per.hit = 100

                    '*******main program loop********
                    end.of.game$ = "N"
                    DO WHILE end.of.game$ =  "N"
                         LOCATE 1,1
                         PRINT "Defender: "; defender.name$
                         LOCATE 2,1
                         PRINT "Score   : " ; score
                    .
                    .

          Look at the third line above. After this line has been
executed, what value do you think is now in the variable
defender.name$ ?

          Let's see. The first and second lines define
first.name$ and last.name$ variables and store a value in each.
The third line adds the two variables together so we would get
"JohnDoe" in the variable defender.name$

          Run this program now. (ALT then R then S)
         See how it prints the name and the score at the top of
the screen?  (DON'T GET TOO ENGROSSED IN THE GAME !! )

          If we wanted a space between first and last names, we'd
have said
          defender.name$ = first.name$ + "  " + last.name$

          The space between the quotes adds the space between
first name and last name in the defender.name$ variable.

          What would happen if we left off the "$" character from
the variable last.name$ on line 2? Try it and see.

          We'd get "Type mismatch" because Basic thinks that
last.name is a numeric variable and we're trying to add it to a
string (alphabetic) variable - which we can't do!


          One final word, which applies to both types of
variables: YOU HAVE TO DEFINE THE VARIABLE BEFORE YOU USE IT. In
other words, you can't say the following:

                    'start of program comment line
                    PRINT SCORE
                    SCORE = 40

          because SCORE has not been defined before the PRINT
command executes. (Remember that variable names can be upper and
lower case letters!). Basic executes your program commands in
sequence from the top to the bottom. When it comes to the PRINT
command (in this case the first command) it doesn't know anything
about the variable called SCORE, so it will set SCORE up with a
value of zero and print zero.

          Note that in the commands
                    'start of program comment line
                    points.per.hit = 100
                    score = points.per.hit

          score  is a valid definition (or first-use) of a
variable; it doesn't have to be defined before with a line like
"score = 0"

          NOW WE'VE EXPLAINED HOW NUMERIC AND STRING (ALPHABETIC)
VARIABLES (OR BUCKETS) ARE CREATED, NAMED AND USED IN PROGRAMS,
WE'RE GOING TO INTRODUCE YOU TO THE MAIN BASIC PROGRAM COMMANDS,
ONE BY ONE.

          FIRST, we'll start with one of the easiest - the CLEAR
SCREEN command.




4.3  BASIC COMMAND:      CLS  (CLEAR SCREEN)
_____________________________________________


     CLS clears the computer screen of everything currently being
displayed and sets the cursor (the flashing underscore that shows
you where your next displayed character will be shown) at the top
of the screen. This instruction only clears the screen, it
DOESN'T clear any memory or re-set any variables. If you had just
displayed the contents of variable SCORE and then followed the
instruction with a CLS instruction, all your variables (including
SCORE) will be exactly as they were just before the CLS
instruction was processed by the computer.

     Pretty easy, huh?  Let's move  on to the next command; the
INPUT command:



4.4  BASIC COMMAND:      INPUT  "text message" ; variable
_________________________________________________________


     Sometimes in your program you will want to get information
from the user at the keyboard; maybe the screen shows a list of
options and you want the player to enter one, or maybe you want
the player to enter their name.  The command you use is the INPUT
command, as follows:

                    INPUT "Enter your name! " ; name$

     name$ is a variable name , and it doesn't have to be
pre-defined; this may be the first time in your program that this
variable has been mentioned.

     When the computer executes this instruction, it will display
the message "Enter your name!" on the next available line of the
screen and the cursor will be positioned immediately after the
message, waiting for the player (or you!) to input their name.
You would then key your name and press the Enter key. The
computer would then take the character string you entered (your
name) and store it in a variable called name$ (as in our
example). You could have called the variable any valid Basic
name, such as FNAME$  or last.name$  etc....

     Now look at this INPUT command:

                    INPUT "Please enter your age: "; age

     Because the variable "age" doesn't have a $ sign after it,
it is a numeric variable. If you enter any non- numeric key (like
"A") the computer will print "REDO FROM START" after you press
the enter key - this is telling you that you had an error in the
input and must key it in again. For string variables (which have
a $ sign after the name), any alphabetic or numeric value can be
entered from the keyboard. For either type of variable, you must
always press the enter key to tell Basic that you've finished
inputting.


Demo Program BAS04.BAS

     Let's change the program we were working with before to ask
for the player's name.  Retrieve program BAS04.BAS

     The first four lines at the top have now been changed to

        INPUT "Enter your first name:  "; first.name$
        INPUT "Enter your last name:  "; last.name$
              defender.name$ = first.name$ + " " + last.name$
        PRINT "Welcome, " + defender.name$ + ". Press Enter to
                                   start."

     Now run the program and watch what happens! (Alt + R + S)



4.5  BASIC COMMAND:        PRINT
________________________________


     PRINT is a Basic command that's a throw-back to the days
when the only output device to a computer was a teletype or
printer. Now, we have video-terminals, but Basic uses the command
Print to display information on the screen. It's all very
confusing, isn't it!  It would have been much easier if they had
made a new command that says DISPLAY, but they didn't and we're
stuck with PRINT. All we have to remember is that when we issue
the Basic command PRINT, we're telling Basic to display what
follows the command on the video-screen.

     So how does this PRINT command work?

     It's pretty easy. You've already seen some examples in the
programs above.



     The format of the PRINT command is

               PRINT  variable1;  variable2;  variable3; . . .

          where variable 1, 2, 3 etc can be a literal string like
          "ENTER YOUR NAME" or any string  variable (for
          example,first.name$ ) or any numeric variable (for
          example,  AGE)

     The following is a PRINT instruction used in the program we
were just looking at:

               PRINT "Defender:  " ;  defender.name$

     If we wanted to print score on the same line, we could
extend the PRINT command to say:

            PRINT "Defender:  " ;  defender.name$ ; " Score: ";
                                   score

     If you don't type the semi-colon (;) between the variables,
the Basic smart-editor will put them in for you anyway.


     You can even do calculations in the PRINT command as the
following will demonstrate:

               CLS
               Age = 15
               PRINT  "I am half the age of a "; Age*2;"year old!
                         How old am I?"
               END



4.6  BASIC COMMAND:      LOCATE
_______________________________


     As each line is printed, the cursor moves down to the next
line. When it reaches the bottom, the lines above it scroll
upward so that the last line printed is always at the bottom.

     Sometimes, however, we want to PRINT information at a
particular place on the screen.   To do this, we have to use the
LOCATE command before we use the PRINT command.

     The video-screen is made up of a number of rows down the
screen and a number of columns across the screen. When you're
printing information in screen mode 1 in Gamebasic, (more about
screen modes a bit later)  there are 25 rows and 40 columns. In
screen mode 2, there are 30 rows and 80 columns.


     The format of the LOCATE command is    LOCATE   row, column

     As an example, LOCATE 2, 5 would move the cursor to the A in
the diagram below. Whatever you then printed, would start from
that position on the screen.


Column:      1 2 3 4 5 6 7 8 9 10 . . . ---> 40

Row       1  . . . . . . . . . . . . . . . . .
          2  . . . . A . . . . . . . . . . . .
          3  . . . . . . . . . . . . . . . . .
          .  . . . . . . . . . . . . . . . . .
          .  . . . . . . . . . . . . . . . . .
          V  . . . . . . . . . . . . . . . . .
          25 . . . . . . . . . . . . . . . . .

     So,  LOCATE 2, 5
          PRINT "START"     would give:

Column:      1 2 3 4 5 6 7 8 9 10 . . . ---> 40

Row       1  . . . . . . . . . . . . . . . . .
          2  . . . . S T A R T . . . . . . . .
          3  . . . . . . . . . . . . . . . . .
          .  . . . . . . . . . . . . . . . . .
          .  . . . . . . . . . . . . . . . . .
          V  . . . . . . . . . . . . . . . . .
          25 . . . . . . . . . . . . . . . . .

     at the top left of the video screen.

     That's all you basically need to know about the LOCATE and
PRINT commands.




4.7  BASIC COMMAND: IF .... THEN  .... ELSE
___________________________________________


     Very often in your program you will want to test the values
of certain variables and take different action depending upon the
outcome.

     Basic uses the IF.. THEN ... ELSE  commands to do this. The
format is

               IF condition.1  THEN action.1  ELSE action.2

     As an example:  in the program we were just looking at, if
we added code to the program to get the player's age and also ask
whether they wanted to play a fast or slow game, we could then
test the replies and make our program take different actions
based on the replies.


Demo Program BAS05.BAS

     Load program BAS05.BAS now and look at the changes.


     You will see that we've added the following lines to our
program at the top:

               PRINT "What is your age, " + first.name$ + "?"
               INPUT age
               INPUT "Do you want to play the slow or fast
                         game(s/f)";game.speed$
               game.speed$ = UCASE$(game.speed$)
               PRINT " "

               start.speed = 40
               IF  ( game.speed$ = "S" AND age > 29 )  THEN
                    start.speed = 30
                    PRINT "Getting too old to play the fast
                              game?"
               ENDIF
               IF age < 8 THEN PRINT "You're rather young for
                              this?"
               IF game.speed$ = "F" THEN
                    PRINT "You better wake up for this one!"
                  ELSE
                    PRINT  "OK - so take the easy option"
               ENDIF
               PRINT "Good luck, " + first.name$ +  "!"
               PRINT "Press Enter to start"
               INPUT " ", dum$

     Before we explain what this whole block of code is doing,
there are a couple of things we should mention.

     1. Why did we include the line
               game.speed$ = UCASE$ ( game.speed$ )
          and what is it doing?

          Well, the keyboard, like a typewriter, has upper-case
and lower-case letters. When we ask the player to enter character
information which we later want to test to see if it's a certain
value, we don't know if they are typing in upper-case or lower
case. If we do a test for a lower-case "f" (for example) and they
typed an upper-case "F", then the test will fail. In other words,
a lower-case "f" is not equal to an upper-case "F".

          There are a number of "functions" in Basic that perform
specific actions on variables. For instance, the SQR function
gives the square-root of a number.  A = SQR(100) will put the
value of 10 into variable A, since 10 is the square root of 100.
The UCASE$ function works on a string variable and converts the
variable to all upper-case letters. So the command

           "game.speed$ = UCASE$(game.speed$) "

will convert all the characters in the variable game.speed$ to
upper-case characters and place the result back in the
game.speed$ variable.

          Now, when we want to test this variable in our program
for a specific value, all we have to test for is the upper-case
letter, since the variable can NOT have lower-case letters in it
after the UCASE$ command.  If we didn't do this, then we'd have
to say in our IF condition

               IF game.speed$ = 'f' OR game.speed$ = "F" THEN
               .....

          There are many Basic functions you can use in your
programming once you become familiar with Basic. The HELP feature
in QBasic (Alt + H) is very comprehensive and will be a good
source of information for you.

     2.   In the Basic language, we don't write "greater than" or
"less than" in our  IF .. THEN ... ELSE .. tests ;  we use
mathematical symbols in their place. The following are the
mathematical symbols we can use in Basic tests :

               >      greater than
               <      less than
               =      equal to
               >=    greater than or equal to
               <=    less than or equal to
               <>    not equal to

     Having covered those two issues, what DOES the above code
actually do?

     A)   If the player selects the slow game and is older than
29, we print the "too old?" message and change start.speed from
40 back to 30. We only do this if the condition above is true (in
other words the player IS older than 29 AND selects the slow
game). Notice that we have more than one action to be taken when
this condition is true. In this case, each action after the THEN
instruction has to be on its own separate line. When all actions
that we want to perform when this condition is true have been
entered, the condition or test has to be closed with an ENDIF
command , again on its own line.

          Notice the brackets around the condition. In Basic, you
can code very complex conditions in one statement (although it's
not recommended that you do) and you can also use the OR operator
; for example
               IF ( (condition1 AND condition2) OR condition3 )
                    THEN ..

          Use brackets to clarify the groupings of your
conditions to reduce logical errors and clarify reading your
program.

     B)    After the first condition has been tested, we drop
down to the next condition (age < 8)  and print the "too young"
message if the condition is true. Notice in this line that since
we only had one action (the PRINT action) we can code the whole
" IF condition THEN action "  on one line and we don't need an
ENDIF at the end.

     C)   After the second  condition has been tested, we then
include a further  test  - whether the player has selected the
fast game. If the player HAS selected the fast game, we print the
"wake up" message. If the player has not selected the fast game
then the ELSE code will print the "take the easy option" message.
Either way, we will print one of the two messages.

     Your IF condition has to be coded on one line; it cannot
span two lines. Where you are entering a long IF condition , the
line you're on will automatically move across to give you more
room to complete the condition.  When you press the Enter key,
you'll go back to column one of the next line. Try this out.
Enter a long comment line (the line should start with a quote or
the characters REM), then press the enter key. Now, with your
cursor back on the long line, press the END then the HOME keys on
the keyboard one after the other and watch what happens. You'll
flip between the end of the line and the start of the line. If
you hold the CTRL key down and, at the same time, press the left
or right arrow keys, you'll go through your long line word by
word.

     It's a very good idea to INDENT your IF statements to
improve readability just like we've done in the above code
(INDENT means to move the commands that are part of the IF and
action logic to the right by a couple of columns).

     NESTED IF's

     You can also have an IF statement following an IF statement.
This is called NESTED IF's. To have more than 2 levels of NESTED
IF's is not recommended since it really makes your program quite
complicated to read. Having said that, here's the format:

                IF condition.1 THEN
                    action.1
                     IF condition.2 THEN
                         action.2.1
                         action.2.2
                    ENDIF
               ENDIF

     You'll note that each IF has to have a matching ENDIF. In
this example, if condition.1 is true, the program will do
action.1 and then it will test for condition.2. If this is true
as well (and only if it's true) then the program will also do
action.2.1 and action.2.2.  If condition.1 is NOT true, the
program will never get to the statement that tests for
condition.2

     We could have coded the first condition in our program above
as follows:
                IF age > 29
                    IF game.speed$ = "S"
                         start.speed = 20
                         PRINT "Getting too old to play the fast
                              game?"
                       ELSE
                         PRINT " I'm impressed! Think you can do
                              it?"
                    ENDIF
                ENDIF

     In the example above, it will only test for game.speed$ =
"S" when  age is greater than 29 and also the ELSE condition (the
"impressed" message) will only print when age is greater than 29
and game.speed is NOT "S"

     If game.speed is NOT S then it must be F,  right?  WRONG! We
don't test after the player has entered the game speed that they
actually DID enter an S or an F. (We'll explain how you can do
that later). So they could have entered T or X or anything.  Can
you see what program BAS05.BAS will do if they enter T?


     They'll get set up to play a fast game, since start.speed is
set to 40 before the IF conditions and is only changed to 30 when
the first IF condition is true. However, the IF game.speed$ = "F"
line will print the "easy option" message because game.speed$ is
NOT equal to "F" (it's a "T").

If you  follow this , then you're REALLY starting to think like a
programmer..... watch out, it could be FUN!

     You can test for anything you want in these IF  THEN  ELSE
conditions, even for specific names that have been input like:

            IF name$ = "dad" THEN
                    points.per.hit = 1
               ELSE
                    points.per.hit = 100
            ENDIF
     but you wouldn't do that, would you? That would be cheating!

     Here's a program for you to follow now:

     IF   you are not quite sure how this all works   THEN
          try making some changes to the program and see what
                    happens
     ELSE
          carry on with the next subject
     ENDIF


4.8  BASIC COMMAND:      GOSUB xxxxxxx
______________________________________


     What we have been working with so far is one program routine
- the main routine. But a main program routine can re-direct
processing (or call) a sub-routine - this is a block of code that
performs a sub- function within the main program. For example you
might want to calculate peoples ages from their date of birth and
the current year (which might have been previously set-up in the
program) in various places in your program.

     When you have such a routine (that is the name we give to a
chunk of program code that performs a specific function) that
will be executed in various places in your program, rather than
duplicate the commands each time, you can simply include all the
program commands in one subroutine and then, each time your
program comes to the point where it wants to execute the
commands, you would simply write  GOSUB  CALC.AGE   (for
example).

     When Basic is processing your program and comes to a GOSUB
command, it then processes all the commands that are in the
subroutine that you've written before continuing with the next
command in the main program.

     However, you must be aware of the following to use GOSUB:

          A)   Your sub-routine has to start with a label at the
front that is the name you have called your subroutine followed
by a colon character (:), and it must be followed by all the code
you want in the sub routine.

          B)   At the end of your subroutine, you must include a
RETURN command, which tells Basic to return to the statement in
the main program that follows the GOSUB statement.

          C)   ALL Subroutines must be located at the end of the
main program - they cannot be at the top or middle.

          D)   Sub routines can call other subroutines. But be
careful you don't call the same subroutine you're currently
executing. This is called RECURSIVE CALLS, and may result in your
program LOOPING. This means that it loops through a couple of
instructions without EVER getting out (and getting very dizzy in
the process!)


               The following is an example of a Recursive CALL:


                    'Main Program code........
                    .
                    GOSUB LOOPTEST
                    .
                    END

                    'Subroutine code..........
                    LOOPTEST:
                                             <----<  This is a
                         A = 1               |    |   tight LOOP!
                         GOSUB LOOPTEST      ->-->-
                         RETURN

               When something like this is coded and you run your
program, it will give you an error message saying "Out of Stack
space".

     Subroutines provide a handy way of reducing your program
size and complexity when you have procedures that need to be
executed from different places in your main program.

Demo Program BAS06.BAS



     Here is an example of a subroutine. Load program BAS06.BAS.
In this program, we've taken all the code we put at the top of
our program we were just working on, and placed it in a
subroutine called GET.NAME which has, as its last line, the
RETURN command. At the top of the program, where we took this
code from, we now have one command saying  GOSUB GET.NAME



4.9  BASIC COMMAND: DO WHILE ... LOOP
_____________________________________


     This command allows you to set up a controlled loop
situation. What does this mean? Well, sometimes you may want to
repeat a section of code until a specific event happens. As an
example, you might want to get input from the user for the
variables above, then process the program, then go back and do it
all over again until the user tells the program to stop.

     The format of the DO WHILE command is as follows:

               DO WHILE   condition
                       action 1
                       action 2
                       action 3
                       .
                       .
               LOOP

     What will happen when the program execution gets to the DO
WHILE instruction?  Well, it will test if the condition is true.
If it is true, it will perform all the actions between the DO
WHILE line and the LOOP line. When it gets to the LOOP line, it
will go back, check the condition again and, if it is still true,
it will repeat the process again. It will continue doing this
until the condition is false. When this happens, processing will
continue from the line immediately following the LOOP statement.

Demo Program BAS07.BAS

     Load program BAS07.BAS There are two examples of DO  WHILE
loops in this program.

     The first example in this program is in the GET.NAME
subroutine, where we ask whether the player wants to play a slow
or fast game. We have included a DO WHILE loop as follows:

          DO WHILE (game.speed$ <> "F" AND game.speed$ <> "S")
             INPUT "Do you want to play the slow or fast
                         game(s/f)";game.speed$
             game.speed$ = UCASE$(game.speed$)
          LOOP



     This code checks that the player enters an F or an S for
game.speed$.

     The first time the program comes to this line, the variable
game.speed$ has not been defined, so it will have a value of
spaces. Since it's spaces (and therefore not equal to an S AND
not equal to an F)  then both our AND conditions are true so the
program goes into the DO WHILE loop and asks for game.speed to be
input.

     Now, lets say the player enters a value of "T". When the
program comes to the LOOP instruction, it goes back to the DO
WHILE instruction and tests the condition again. This time
through, game.speed$ is still not equal to "F" and not equal to
"S" so the program goes into the DO WHILE loop again.  It will
keep asking for game.speed until the player enters either an S or
an F.

     The second example is in the main program, where we have
coded the following:

          play.it.again.sam$ = "Y"
          DO WHILE play.it.again.sam$ = "Y"
               CLS
               GOSUB SETUP
               end.of.game$ = "N"
               DO WHILE end.of.game$ = "N"
                    GOSUB GAME
               LOOP
               INPUT "Play it again?  (Y/N) : ",
                         play.it.again.sam$
               play.it.again.sam$ = UCASE$(play.it.again.sam$)
          LOOP
          END

     This block of code has a DO WHILE ...LOOP within a DO
WHILE.... LOOP (NESTED DO's!).  The outer (or first ) DO
WHILE.... LOOP controls how many times we play the game while the
inner DO WHILE.... LOOP is the main program loop in our program
that calls the Game. The subroutine GAME includes the basic
instructions for our game.

     When the game finishes, (for example, all the aliens are
shot out of the sky, or they shoot our cannon) the code in our
GAME subroutine will set the variable end.of.game$ equal to "N".

     When this happens, the inner DO WHILE... LOOP will be
cancelled and the instruction below it will be processed - the
INPUT instruction asking if the player wants to play the game
again.

     The program then comes down to the LOOP instruction below
this one, which tells it to go back to the DO WHILE
play.it.again.sam$ = "Y" line (since the inner loop has been
cancelled). It then tests if the variable play.it.again.sam$ is
"Y".

     If they had answered anything other than  "Y", then the
program will cancel the outer DO WHILE... LOOP and will continue
its processing from the instruction immediately below the last
LOOP command, which is END (terminate the program).

     If they had answered "Y", then the program will set
end.of.game$ equal to "N" then activate the inner DO WHILE....
LOOP again and re-start the game.

     Why did we set the variable end.of.game$ equal to "N" before
we went into the DO  WHILE  loop? Do you know?

     Well, what would happen if we left it out?  Move the cursor
to the front of the end.of.game$ = "N" line and enter REM or a
single quotation mark (this turns it into a comment line as
opposed to a program line that basic will execute).

     When you run the program now, the game starts up, then goes
immediately to the "Play it again?" line. What's happened?

     What's happened is that the program has skipped the REM
end.of.game$ = "N" command and executes the next program command,
which is now

          DO WHILE end.of.game$ = "N"

     but it doesn't know about end.of.game$ at this point since
the only place the variable is mentioned now is in the GAME
subroutine, where it sets it to "N" when the game finishes.  So,
end.of.game$ is not equal to "N" (it's blank or null) and the
program bypasses all the code in the inner DO WHILE...LOOP
section and goes to the next immediate instruction after the
LOOP, which is the INPUT instruction asking if the player wants
to play the game again.

     WARNING: YOUR PROGRAM CAN GET INTO A NEVER-ENDING LOOP
SITUATION IF THE DO WHILE CONDITION NEVER GOES FALSE (ie
end.of.game$ never gets changed to a value other than "N"). IF
THIS HAPPENS, PRESS THE CONTROL and BREAK KEYS AT THE SAME TIME
TO STOP YOUR PROGRAM.

     There's only a few more pages to read, then we'll get into
some really fun stuff, so hang in there! OK?



4.10 BASIC COMMAND:       FOR .... NEXT
_______________________________________


     Where we know that we want to execute a process or section
of code a specific number of times until we move on to the next
process in our program, we would use the FOR ... NEXT command.

     It's format is
          FOR numeric.variable = start.value TO end.value STEP
                    step.value
          .
          .
          NEXT numeric.variable

     Let's take an example.
     Lets say we wanted to calculate the squares of numbers from
1 to 10. (The "square" of a number is the number multiplied by
itself. Don't ask me why we want to calculate this, but we do,
OK!)

Demo Program BAS08.BAS

     Load program BAS08.BAS
     Here's the code:
               CLS
               FOR Number = 1 to 10
                    Square = Number * Number
                    PRINT "Square of " ; Number ; " is " ; Square
               NEXT Number
               END

     This is how the FOR ....   NEXT instruction works:

     A)   When Basic first comes to the FOR Number = 1 to 10
line,  it will set up a control loop based on Number, which it
initially sets to 1.

     B)   Then it executes all the following code using Number
with a value of 1 until it reaches a NEXT instruction.

     C)   When it reaches a  NEXT instruction, it adds one to
Number and goes back to the top line ( FOR Number =  . . . . ).

     D)   The first thing it does now is test to see if Number is
between 1 to 10. It is, (Number is now 2) so it goes through the
code again, but this time with number set to 2. When it gets to
the NEXT instruction, again it adds 1 to Number (making it 3) and
goes to the top again.

     And so on, until number is equal to 11.

     E)   When this happens, the program will cancel the FOR NEXT
Loop (since number is not between 1 and 10) and continue with the
instruction following the NEXT Number line.

     The numeric variables 1 and 10 after the FOR Number command
could have been formulas; for example

          FOR Number = (low.num * 2) TO (high.num / 3)

     WARNING: BASIC WILL BYPASS THE FOR..NEXT CODE IF, WHEN IT
GETS TO THE "FOR NUMBER = .... " LINE IT FINDS THAT THE START
VALUE IS ALREADY GREATER THAN THE END VALUE.

     If we had wanted to do this routine for every alternate
number, we could have coded

          FOR Number = 1 to 10 STEP 2
          .
          .
          NEXT Number

     Then, we would only have printed the squares for numbers
1,3,5,7 and 9 since, when Basic gets to the NEXT Number line, it
adds 2 to Number and not 1.

     You will find some other examples of FOR . . NEXT LOOPS when
we get into the GameBasic GAME commands, which won't be long now.



4.11 BASIC COMMAND:  CALL xxxxxxxx (var1, var2, var3....)
__________________________________________________________


     The basic command CALL is used to run a sub-program. It is
not in the scope of this document to explain the inner workings
of sub-programs and how you  code them. However, sub-programs are
very similar to GOSUB routines, which we've explained above. The
sub-program contains lines of code that get executed when the
CALL is issued. You won't see the program code in your main
program - you need to press certain key combinations to look at
sub-programs. This command is included in this document since all
GameBasic routines are written as sub-programs. Your game
programs will make calls to these sub-programs and you therefore
have to know something about how to pass variables to the
GameBasic sub-programs.

     Each GameBasic sub-program expects to be sent a specific
number of variables, each of a certain variable type (for
example, a numeric variable followed by a string variable
etc...). If a routine expects to get 5 variables, you must pass
it 5 variables - no more and no less, and they must be of the
variable types that the routine expects to receive.

     Sounds a bit confusing?  Well, let's take a simple example
to show how calls to sub-programs are made.

     Let's assume that you want to call a previously-written
sub-program that prints a message starting at a specific row and
column on the screen. The sub-program that was written expects to
be sent three variables (or parameters) - row, column and
message; in that order. When it is called, it will take the value
of the variable supplied for the message parameter and print it
at the location specified by the row and column variables
supplied. Each time you call this sub-program, you can supply a
different value for row, column and message and the sub-program
will work with the new values. Here's an example of a call to
this sub-program, which we've called PRINTMESS for the purposes
of this example,  asking it to print "START" at row 2, column 5:

               CALL PRINTMESS (2,5,"START")

     The first variable that PRINTMESS expects to receive is a
numeric variable representing the row, followed by another
numeric variable for the column followed by a string variable
containing the characters that you want it to print.   You must
supply the variables (or parameters) in that order.  Now what
would happen if you didn't?  Look at the following three examples
of calls to PRINTMESS:


          row = 2
          col = 5
          mess$ = "START"
          CALL PRINTMESS (mess$, row, col)<-------- call no 1.
          CALL PRINTMESS (col, row, mess$)<---------call no 2.
          CALL PRINTMESS (row, col, mess$, reply$)<--- call no 3.

     Call number 1 won't work at all because PRINTMESS was told,
when it was written, that the first parameter it will be sent
will be a numeric parameter and here we are trying to send it a
string parameter! Basic is smart - it says "Oh No No No ... ! ,
you can't do that, stupid". Actually, it's a bit more polite than
that; it says PARAMETER TYPE MISMATCH, but we all know that it
really wanted to say the former!  When you see this message, it's
telling you that one of the parameters you've included in your
CALL list is the wrong variable type.


     Call number 2 will work, but do you think it's going to work
correctly? Now, you're going to have to pay attention to this, so
sit up straight and listen!.      PRINTMESS expects to receive
three variables in the following order - row, column and message.
Call number 2 will only work properly if you really wanted to
print START at row 5, column 2 (as opposed to row 2, column 5),
because that's exactly what you're sending the PRINTMESS routine
in its CALL parameters. It doesn't know (or even care) that
you've called the variables you're passing to it "col" and "row";
as far as it's concerned, the first parameter it gets is the row,
the second is the column and so on. It will take the value in
"col" and use that for the row to start printing at, the value in
"row" and use that as the column etc...

     Call number 3 will not work either, since we're sending
PRINTMESS four parameters and we told it when it was written that
it will be sent three. When you send more than or less than the
correct number of parameters to a CALL routine, you'll get the
Basic error "ARGUMENT COUNT MISMATCH". In other words, Basic is
saying "Woa! You told me you were going to send me three
parameters and here you are sending me 123! What gives?"


     Now, let's take an example of a real call to a GameBasic
routine:

     One of the GameBasic CALL routines (the CALL CREATE routine)
is a routine which you can call to create a sprite and start it
moving (more about sprites later). The format for the CALL is

       CALL CREATE ( sprite.no, char.no, col,  row,  speed,
                pixspermove, direction,  horiz$,  vert$,  track$)


     There are 10 variables in the brackets. When you call this
routine you must include 10 variable names or values exactly.
     An example of a valid CALL would be

          start.row = 10
          pixs = 4
          vertical$ = "N"
          CALL ACTIVE ( 1, 3, 12,  start.row,  20,  pixs,  90,
                       "Y", vertical$, "0")

     As you can see, numeric and alphabetic values can be passed
to the routine by either including the actual number or
characters (characters must be enclosed in quotes) OR including
the name of a variable that contains the number or characters you
want to pass to the routine. Each variable or value included in
the brackets must be separated from the next one by a comma.

     When the routine has completed its processing, Basic will
execute the next instruction after the CALL.

4.12 BASIC  ARRAYS :     DIM
____________________________


     Arrays are not commands, they're a method of holding
variables in memory, and are very easy to understand.

     Let's go back to our bucket's again. (remember them?)

     When we define an ARRAY, we can create a number of buckets
(or variables) in memory, all of the same type (that is, all
numeric or alphabetic) and give them a common name. Let's do this
now. Let's draw 4 buckets and call them all PLAYER.NAME$



<--------------------PLAYER NAMES---------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4


     For each array that we use (and we can use and define a
number of different arrays in our program), we must tell Basic at
the very top of our program (not in a subroutine) about the array
so that it can set up a special area in memory to hold the array
values. We do this by the command

               DIM   PLAYER.NAME$(4)

     The 4 in the brackets tells Basic that we want to have 4
buckets  (or elements, which is what we call array buckets)  in
our array called PLAYER.NAME$

     Now, we can enter a separate value into each element
(bucket) by simply specifying which PLAYER.NAME$ element we want
to put the value into;   number 1, 2, 3, or 4 . We do this by
using what we call a subscript, which is just a number or
variable containing the number of the element (bucket) we want to
point to.

     We would add "JOHN" to PLAYER.NAME$ element  1 by coding

      PLAYER.NAME$ (1) = "JOHN"



<--------------------PLAYER NAMES---------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|  JOHN   |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4


     If we also wanted to move "MARY" to the second element of
our array we would code

PLAYER.NAME$ (2) = "MARY"



<--------------------PLAYER NAMES---------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|  JOHN   |    |  MARY   |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4

     We could also have used a variable name to indicate which
element we wanted to move the value into.

     For example,
               subscript  = 2
               PLAYER.NAME$ (subscript) = "MARY"
     will do exactly the same as the previous example.

     Now, lets set up another array and call it TOTAL.SCORE  It
will also have 4 elements or buckets. Here's the code to do this:

               DIM  TOTAL.SCORE(4)
               TOTAL.SCORE(1) = 2000
               TOTAL.SCORE(2) = 4000


     As you can see, we've also moved some values into the first
two elements of this new array.

<--------------------PLAYER NAMES--------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|  2000   |    |  4000   |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4

Demo Program BAS09.BAS

     We can use arrays like this to hold players names and scores
while our game is being played and show all the players names and
scores on the screen each time a game ends.  Retrieve program
BAS09.BAS and look at the changes that we've added to the program
at the top and also in a new subroutine called PRINTSCORES. The
program now loops through the "Do you want to play again" process
4 times controlled by a variable called game.number. At the end
of each game, we add the player's name to the next available
element in PLAYER.NAME$ array then we add the score to the same
numbered element in TOTAL.SCORE array then print out the full
contents of each array before we start the next game.

     The example above is an example using two one-dimensional
arrays, since each array has only one variable (one of them holds
a name and the other array holds total points) and we only need
one subscript to refer to each array's elements.

     But with arrays, we can have 2 or more dimensions.
Visualising a 2 dimensional array is not difficult, but it gets
increasingly more difficult to visualize three or more
dimensions. However, you'll hardly ever have the need to have an
array of more then two dimensions.

     Let's assume that we also wanted to hold the players age in
an array. Now, we could simply set up another array and call it
PLAYER.AGE      But we could also add another dimension to the
TOTAL.SCORE array. Let's call the array PLAYER.INFO rather than
TOTAL.SCORE and we'll make it a two-dimensional array so that it
can have an element to hold total.score as well as an element to
hold player.age.



     The array can be visualised as follows:


<--------------------PLAYER.INFO---------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         | SCORE
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         | AGE
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4

       Because this array has two dimensions (there are elements
down as well as elements across), we define the array as follows:

               DIM   PLAYER.INFO ( 4, 2 )

     The first number in the brackets, the 4, tells basic that
the array is 4 elements wide. The next number, the 2, tells basic
that the array is 2 elements deep.

     Now when we want to refer to a specific element in the
array, we have to give two subscripts in our command; one to tell
basic which column we want (from 1 to 4) and the other to tell
basic which row we want (either the first row - that we're going
to be using to store Score in - or the second row - that we're
going to be using to store player's age in)



     Here is how we would store player 3's score and age:
               PLAYER.INFO( 3, 1 ) = score
               PLAYER.INFO( 3, 2 ) = age



<--------------------PLAYER.INFO----------------------->

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         | SCORE
|         |    |         |    |  23000  |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4

|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |    15   |    |         | AGE
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
|         |    |         |    |         |    |         |
 ----------     ----------     ----------     ----------
     1              2              3              4


     Now that's not too difficult, is it?

Demo Program BAS10.BAS

     Retrieve program BAS10.BAS  and look at the changes. In this
program we've used a one dimensional array as in the previous
program to store the top 10 player's names, and we've added a two
dimensional numeric array called PLAYER.INFO to keep track of the
top 10 player's scores and ages. At the end of each game, we
display the top 10 players in descending total.point sequence.
Unfortunately, when the players exit the game, all information
about players and scores that we've been holding in the arrays is
lost. To keep it, we would have to write the information to a
file and read it back in at the start of each game. However, that
is beyond the scope of this manual.



4.13 Basic Arrays  :        REDIM
__________________________________


     The REDIM Basic command is a handy way of resetting an
array's values to either zeros (if it's a numeric array) or
spaces (for a string array).

     The format of the instruction is:

               REDIM  array.name ( n1,  n2, . . )

     where array.name is the name of the array you want to
initialise and n1, n2 are the dimensions of the array.


     NOTE: The array must have been set up by a previous DIM
instruction and the dimensions n1, n2 etc.. must not be greater
than the dimensions the array was first set up with.


     AND NOW   -    THE LAST TOPIC BEFORE WE GET INTO SOME
SERIOUS GAMES  !



4.14   DEBUGGING YOUR PROGRAM
______________________________


     When you start testing a new program, you'll probably find
that it's doing very strange things initially. You've got some
errors in the program and you need an easy way to find them!
Well, QBasic provides a method of de-bugging your program  to
help you find out where those errors are.  We call program errors
BUGS! This word came into common usage from the early days of
computers, when they were made of valves instead of the chips
that we have nowadays. One day, the computer the scientists were
working on developed a problem which they couldn't explain until
one of the scientists opened the computer and found a dead moth
fused to one of the hot valves. After he removed the moth, the
computer worked perfectly - but ever afterwards, whenever
computers displayed errors (even programming errors) they are
referred to as BUGS! Aren't you glad you know that now?

     Back to our discussion on debugging your program (or getting
the moths out!).


     We're going to take program BAS10.BAS as an example, and
show you the code that initially writes the 30 aliens to the
screen. Retrieve the program now and page down through the
program until you come to the SETUP subroutine. Look through that
sub routine until you see the following code:

          ' ------- following block sets up alien sprites
           alien.spriteno = 10
          FOR row = 10 TO 50 STEP 20
               FOR col = 30 TO 300 STEP 30
                    CALL CREATE(alien.spriteno, 2, col, row,
                              start.speed/10, start.speed/10,
                               180,"W","W", " ")
                    alien.spriteno = alien.spriteno + 1
               NEXT col
          NEXT row

     The CALL CREATE line is the line that sets up an alien
character or sprite on the screen. We'll explain later what the
values in the brackets mean.

     As you can see, this is a nested FOR NEXT block of code. For
each of rows 10, 30 and 50 (since step value is 20) we create
aliens in columns 30, 60, 90, etc... up to column 300 (since step
value is 30)

     Let's watch this as the program actually performs the
instructions, but before we do this, we're going to add one line
to the program to help us in our debugging. Just before the CALL
CREATE line, add the line

               LOCATE 20,1  : PRINT "Row="; row; "Col="; col

     (note that the colon lets us code two instructions on one
line)

     Have you added the line?  OK.  Now bring the cursor to the
FOR row = ..... line and press the F9 key. The line will now be
highlighted. This sets up a break point in the program. What this
means is that when we run the program and it gets to the line
we've highlighted with the F9 key, Basic will temporarily stop
the program and display our program code at this break point.
Note that you can have multiple break-points on in your program
at the same time, you're not just restricted to one.

     Just try it now. Press F5. This will start the program
running. It will go through the regular steps where it asks for
the players name etc,.. but after that (before the games starts)
it will now break at the place you highlighted and you will see
your program code on the screen at the breakpoint you selected.


     Now press F8. The F8 key tells Basic to perform the next
instruction only. Using F8 you can step though your program one
line at a time and watch how the program performs.

     So now we've performed the FOR row = ..... instruction,
Press F8 again and it will perform the FOR col = ....
instruction.

You didn't see anything happen did you! That's  because all the
activity was internal, setting up the row and col loops. Let's
see what row and col actually contain, shall we?


     Press F8 two more times. The line

     LOCATE 20,1:  PRINT "Row="; row ; "Col="; col

     should now be processed but again, you didn't see anything
right? It should have printed the values of row and col on the
screen! Well, don't despair, it did. It's just that we're
currently looking at the program and not the output screen. Press
F4, and you'll flip to the output screen where you should see

               ROW=10  COL=30

printed, and the canon at the bottom of the screen.

     Now press any key and you'll flip back to your program code.

    Pressing F4 followed by any key will flip between the output
screen and the program code.

     So now the line CALL CREATE....  is the next to be
processed.

     If we pressed F8 now, we'd get passed to the first
instruction in the CREATE sub-routine, and we'd then step through
the entire subroutine, line by line. This is quite lengthy, and
we know this works, so we tell Basic to process the whole
subroutine (or procedure) and break when it gets back to our main
program - the instruction immediately after the CALL CREATE line
- by pressing the F10 key (Procedure step) instead of the F8 key.

Press the F10 key now.
Now flip to look at the output screen (press F4) and you should
see the first alien on the screen.


     Press F8 four times then look at the output screen again and
you should see that row is still 10 but col has been increased to
60. Now, when you run the program to the point after the CALL
CREATE command and you press F4 you should see the second alien
on the screen.

     Continue doing this for as long as you want and you will see
all the aliens being written to the screen. You will also see the
nested FOR instructions working.

     HINT:  In Gamebasic, when we want to look at the contents of
a variable, include the LOCATE x, x command before the print
command. If you don't do this, then the PRINT command on it's own
will move the screen up by one line and all your game characters
will get moved along with it.

     HINT: After you've finished using a LOCATE x,x: PRINT line
for your debugging, you can leave it in your program in case you
need it again by simply inserting a single quote at the beginning
of the line. It is now a comment line. When you want to use it
again, just take out the quote.

     HINT:  QBasic has a pretty neat field-sensitive HELP
feature. When you're in the program edit screen and you're unsure
of what a QBasic command does, position the cursor under the
command (for example, under PRINT) and press the F1 key. QBasic
will then show you a series of help screens on the PRINT command.

    Note that this doesn't work for GameBasic commands.

     HINT: Unless you have coded your own subroutines (GOSUB
xxxx, remember?) and want to de- bug them, it will probably be
easier if you use the F10 key all the time, instead of the F8
key. "Oh wonderful. NOW he tells us!" I can hear you saying.
Sorry, but we had to cover the above so you understand the
distinction between single-instruction steps (F8 key) and
full-Procedure steps (F10 key).

     This debugging process is somewhat laborious, but it's the
best that QBasic has to offer. Other languages (including
Microsoft's QUICKBASIC, which is an upgraded version of QBasic)
have much better debugging features.

     Well, that's it.
     If you've followed the above, then CONGRATULATIONS!
     At long last you're now ready to move on to some Games ....

Get Ready ..... GO !



________________________

5.   GAMEBASIC COMMANDS.
________________________


5.1  Introduction.
_________________


     GameBasic provides many features to simplify the process of
developing games. That's why it was developed; so you can
concentrate on the logic in your game program rather than the
technical complexities involved in displaying sprites on the
screen, moving them around, testing if they've run off the side
or if they've hit another sprite.. (remember our definition of a
sprite being a character that appears on the screen, moves in a
certain direction and speed and then (maybe) disappears...)

     You define how your characters will look by setting up char$
arrays containing your character definitions and then calling the
DEFINECHAR routine. You create and start sprites moving through
the CALL CREATE command and you set-up your control sprites
(sprites whose movement you control through the keyboard, like a
cannon etc..) through the CALL CONTROL command.

     The CALL CONTROL command is a very powerful command; in it
you can define which character the control sprite should appear
as depending upon it's aspect (in other words, when it's pointing
up, down, to the left etc..), which keys control its movement and
which character to fire when the CALL SHOOT command is issued.
It's the command which has the greatest number of parameters in
its CALL list and is the most powerful command in GameBasic - but
normally you'll only need one of these commands in your game.

     Finally, there are CALL commands which allow you to test if
a sprite is still active, change the character a sprite is being
displayed as, delete a sprite, test if one or more sprites have
hit each other and so on.

     Now we've covered some of the introductory aspects to
GameBasic, I promised we'd get into programming, so let's do that
now. We're going to work together to develop a pretty
sophisticated computer game - we're going to do a version of
Alien Invaders - where nasty aliens drop down the screen and take
over the world. We'll have a cannon at the bottom of the screen
which will be controlled by the keyboard and can fire missiles up
at the aliens. We'll have to test if a missile has hit an alien,
if we've hit all the aliens, if the aliens have hit our cannon
and also if the aliens have landed..

First, we have to do a flowchart of the logic that we want in our
program. Can you have a go at that now! Don't look over the page
at the answer yet (although in programming, there is hardly ever
one and only one answer or solution!).


Here's one suggested flow chart, which we'll be working with as
we develop our program.

          Define Characters
          (alien, cannon, missile, fireball)
                  |
                  V
            Create Alien and Cannon sprites
            Define Control Sprite (cannon)
                  |
                  V
 -->------->Move Sprites
|                 |
|                 V         Yes
|        FIRE key pressed? -------->Launch Missile
|                 |                        |
^              No |------------<----------<
|                 |
|                 V       Yes            Yes
|    Is a missile active? --->Has it hit---
|                 |             an alien?  |
|                 |              |         V
|                 |              |     Delete Missile
|              No V           No V     Delete alien
|                 |              |     Add to score
|                 |              |         |
^                 |-------<-----------<----
|                 |
|                 V            Yes
|           Are all aliens hit?--->Print"WellDone"
^                 |                Stop
|              No |
|                 V            Yes
|        Has Alien hit cannon? ---->Print"You got
|                 |                          hit"
|              No V                 Stop
|                 |           Yes
^           Has Alien landed? --->  Print"We Landed"
|              No |                 Stop
| (Loop Back)     |
 -<-------------<-


     We're going to develop this program in stages, taking each
stage at a time and gradually introducing you to GameBasic CALLs
and the parameters you have to pass to them.



     First, we're going to define our characters and just display
them on the screen to make sure we've got them exactly how we
want them.


5.2  GAMEBASIC BASE PROGRAM
____________________________

Demo program GAME01.BAS

     Get into the Basic environment and retrieve program
GAME01.BAS

     As soon as you have got the program in the edit screen, save
it under a different name so you can call back GAME01.BAS later
if you need to. Remember, you save the program as a different
name by pressing Alt then F then A, then you enter the name you
want to call it (GAME01xx where xx is your initials - you don't
have to put .BAS at the end, Basic will do this for you
automatically). As you work through the following, save each GAME
program under your own initials as above.

     Look at the program.   What we are working with now is the
GameBasic "Base" program with some lines of code added to define
your characters. There are a couple of lines at the top of the
program and also at the bottom which are GameBasic program lines.
This code (another name for a block of program lines) is boxed by
asterisks to identify it as GameBasic code.

     YOU MUST NOT CHANGE ANY OF THESE LINES OR ELSE GAMEBASIC
WILL STOP WORKING.

     In between these top and bottom blocks of lines is the code
to define and display your characters. Also, the program includes
all the GameBasic CALL Sub Programs -  you can't see these but
they are there (NOTE: Basic provides special keys to look at sub
programs but it's not in the scope of this manual to explain this
aspect of Basic)


     Whenever you start coding a new program, you will call up
the GameBasic "BASE" program GBASE.BAS and immediately save it
with the name you want to give to your new game program. All
subsequent programming you do will be done with YOUR program's
name - YOU CAN'T CHANGE THE BASE PROGRAM.


     Look at the code between the GameBasic code. See how we have
defined the alien, cannon and missile characters? The cannon
character is shown below.

5.3       CHAR$   -  Character definition.
_________________________________________

     For each character you want to create, you simply fill-out a
two-dimensional array of 16 horizontal dots by 12 vertical dots
(ie a grid of 16 x 12) and tell the computer which colour you
want each dot to be shown as. The combination of dots make up
your character. You MUST use the array called  char$ for this.

     The first dimension (ie the 1 in "(1,12)" for example )
represents the character number. In the example below, the
character number for the cannon is 1.

     The second dimension represents the line of the character,
and can go from 1 to 12.

     char$(1, 1) = "                "
     char$(1, 2) = "                "
     char$(1, 3) = "                "
     char$(1, 4) = "                "
     char$(1, 5) = "        7       "
     char$(1, 6) = "        7       "
     char$(1, 7) = "       373      "
     char$(1, 8) = " 33333333333333 "
     char$(1, 9) = "333 3 3 3 3 3 33"
     char$(1,10) = " 33333333333333 "
     char$(1,11) = "  6 6      6 6  "
     char$(1,12) = "   6        6   "

     HINT: To save internal memory where you have a lot of
different characters, you can remove char$ lines which don't
contain any numbers between the quotes (for example, lines 1, 2,
3 and 4 above). Also, to save internal memory space, you can
place the last quote immediately after the last number in the
line (for example, lines 5 and 6 could be shortened to
      char$ ( 1, 5 )  =  "           7"    etc...)

     The numbers between the quotes represent the colour of the
pixel (or dot) on the screen as follows:

     0 or space = Black or
         Background colour         8 - Grey
     1 - Blue                      9 - Light Blue
     2 - Green                     A - Light Green
     3 - Cyan                      B - Light Cyan
     4 - Red                       C - Light Red
     5 - Magenta                   D - Light Magenta
     6 - Brown                     E - Yellow
     7 - White                     F - High Intensity White

     Look at the definition for the other characters. Can you see
how they will look when they're shown on the screen?


5.4  CALL DEFINECHAR
____________________


     Example:
     CALL   DEFINECHAR

     This is the GAMEBASIC command that actually reads your
character definitions and turns them into screen definitions. It
does not need any parameters in brackets after the DEFINECHAR.
This process takes a couple of seconds, depending upon the speed
of your computer and the number of characters you have defined.
It is suggested that you define ALL the characters your game will
be using up front and CALL DEFINECHAR once at the start of the
game.


5.5    CALL  CREATE (sprite.no,  char.no,  col,  row,  speed,
                    pixspermove, direction,  horiz$,  vert$,
                    track.no)
______________________________________________________________

     Example:
     CALL CREATE ( 1, 1, 50, 10, 40, 6, 180, "D", "D", " " )

     This is the command that creates a sprite, but before we
discuss it, we should mention one thing.

     In the section that explained the PRINT command, we said
that there were 25 rows and 80 columns on a screen.

     Well, that's true when you're "Printing" information, but
GameBasic commands use graphics characters, and these use a
different Screen "Mode" in Basic - Graphics mode.

     The only difference you have to be aware of is that instead
of only being able to work with 25 rows and 80 columns, in
graphics mode there are effectively 200 rows (from 0 to 199) and
320 columns (from 0 to 319) as shown below. (Note that the PRINT
command can still only reference 25 rows and 80 columns - it's
only the GameBasic graphics commands that can use the higher
numbers ).

     Each of the following positions on the screen represents
what we call a pixel - the small dots that go to make up the
characters you see. That's what you are defining when you code
your character definitions in char$  - where you want each pixel
to appear in your character and what colour it should be.
     IN ALL GAMEBASIC COMMANDS THAT FOLLOW WHICH INCLUDE A ROW OR
COLUMN PARAMETER, THE MAXIMUM VALUES YOU CAN ENTER FOR ROW AND
COLUMN ARE 187 AND 303 RESPECTIVELY.

     Now look at the GAME01 program you have on your screen.
In this program, we've created one sprite each for the cannon,
alien and missile and defined them as sprite numbers 1, 2 and 3
respectively. Can you see the CALL CREATE command?


     The parameters that must be passed to the CALL CREATE
subroutine are:

     sprite.no  -   This  is a number from 1 to 90 representing
                    the number you are assigning to this sprite.

     char.no    -   This is the character number that the sprite
                    will be displayed as. The cannon is being set
                    up as sprite.no 1 and is using char.no 1. The
                    char.no is taken from the group of lines you
                    used to define the character you want to use
                    here  (ie. from the array CHAR$(1,n) )

                     Char.no 1 happens to be (surprise, surprise)
                    the cannon character definition. If we wanted
                    this sprite to take on the shape of another
                    character, we would have used another number.

     col        -   This is the column (from 0 to 303) where we
                    want this sprite to be first displayed.

     row        -   This is the row (from 0 to 187) where we
                    want this sprite to be first displayed.

     speed      -   This is the speed we want this sprite to
                    start moving at.  The value can be from 0 to
                    40.

                    0 indicates a sprite that doesn't move.
                    This might be a land mine or a rock in a Tank
                    Battle game, for example.

                    1 indicates a very slow moving sprite.

                    40 indicates a very fast moving sprite.

                    Note that the sprite won't start moving
                    until we issue the CALL MOVE command (see
                    next).

     pixspermove -  The number of screen pixels that this sprite
                    should move by  every time it moves.This
                    value is normally from 1 to 6.
                    A low value will give a smooth-moving (but
                    somewhat slower) sprite. A higher value will
                    give a faster moving sprite but its motion
                    may appear more jerky.

     direction   -  This is the angle at which the sprite should
                    move.
                      0   degrees is straight up.
                      90  degrees is to the right
                      180 degrees is straight down.
                      270 degrees is to the left.

                    In-between values can also be defined. For
                    example, a sprite that moves diagonally from
                    the bottom left to the top right would have
                    an angle of 45 degrees.

     horiz$     -   This parameter is a string parameter and
                    should be enclosed in quotes. It defines what
                    should happen to the sprite when it reaches a
                    screen edge while it is travelling
                    horizontally (ie the left or right side of
                    the screen).

                    "W" - sprite will wrap around the
                    screen, appearing on the opposite side (like
                    an alien descending at an angle)

                    "D" - sprite will be deleted

                    "S" - sprite will stop when it reaches the
                    edge (ie, a cannon)

                    "B" - sprite will bounce off the edge.

     vert$      -   The same definition as above for horiz$,
                    but controls what happens to the sprite when
                    it reaches a screen edge while it is
                    travelling vertically (ie the top or bottom
                    of the screen).

     track$     -   This is the letter of the track that this
                    sprite should follow. For a more detailed
                    explanation of tracks, see CALL TRACK in
                    section 6.6.  If you're not using the TRACK
                    feature of GameBasic, enter a space or null
                    here ("").

     NOTE: At any time on your program, you can re-create a
sprite using the CREATE command, even if it is currently active.
The current sprite will be deleted and the new one will be
created. This is useful when the sprite has reached a screen
border and you wish to re-position it.


5.6      CALL    MOVE
_____________________


     Example:
     CALL    MOVE

     This command MUST be included in the main loop of your
program. This is the command that moves the sprite and should
normally be the first command you code in your main-program loop.
If you don't include this command, those pesky little sprites
won't move at all.

     NOW IT'S FUN TIME.

     Press Alt, then R then S (Run, Start) - or alternatively,
press F5 (which is the equivalent key to start running a basic
program). You should now see your alien , missile and cannon
sprites appear on the screen.

     Why does the line "Press any key to continue" come up on the
screen? The reason is that we don't have a loop in the program
just yet to continually execute the MOVE command. The program
executes the MOVE command once, then comes to the end. Basic then
steps in and says "OK, your program's finished, press any key to
continue" - or words to that effect. We'll add a loop later, but
for now you should practice making changes to the character
definitions and the positions on the screen that the sprites are
first displayed.  Initially, only make one change at a time and
watch what happens.

     If you really mess the program up, don't worry - you have
two options.

          1. You can retrieve the version you saved with your
initials by pressing Alt then F then O, select the program
version with your initials and reply "NO" when Basic asks if you
want to save the program you've just been working on

       OR

          2. You can retrieve the original GAME01.BAS program and
save it again under you initials (GAME01xx), again replying "NO"
when Basic asks if you want to save the program you've just been
working on.

     Once you're happy that you can make these changes, carry on
reading.


Demo program GAME02.BAS

     OK - so you've just run your first GameBasic program. Not
Bad!

Now, retrieve the program GAME02.BAS

     Look at this program. It's very similar to the previous one,
except that now we have included a couple of lines to set up a
control loop around the MOVE command.  Do you see them?  Now,
when you run this program, the sprites will move for a few
seconds before the value in variable J is greater than 2000.

     NOW, PRACTICE MAKING CHANGES TO THE CALL CREATE COMMANDS -
CHANGE THE SPEED, PIXSPERMOVE, DIRECTION, HORIZ$ AND VERT$ VALUES
AND WATCH WHAT HAPPENS.

Again, initially, only make one change at a time.

     Once you are happy and understand how changing the values
changes the way the sprite moves, you can continue reading.

Demo program GAME03.BAS

     Now retrieve program GAME03.BAS

     This program builds on what we've developed so far except
for the time being we've stopped showing the missile sprite.
We'll add the missile sprite back in later when we make it a
sprite that's "fired" by the keyboard.

     Instead of displaying just one Alien sprite we've changed
the program to display 30 aliens arranged in three rows of 10. To
do this, we've used the FOR... NEXT instruction as follows:
                 .
                 alien.spriteno = 10
                 FOR row = 10 to 50 step 20
                    FOR col = 30 to 300 step 30
                         CALL CREATE(alien.spriteno, 2, col, row,
                                   5, 5, 180,
                                         "W" , "W", " ")
                         alien.spriteno = alien.spriteno + 1
                    NEXT col
               NEXT row
               .

     Let's explain what's happening here - it's not too
difficult.

     A)   Before we drop into the first FOR..NEXT loop, we set
alien.spriteno equal to 10. We're going to number our alien
sprites from 10 to 39 (that's 30 of them). After we've created
each alien sprite through the CALL CREATE command, we add 1 to
alien.spriteno so that next time through the loop the sprite
number will be 1 higher (for example, the second time through the
loop, alien.spriteno will be 11).


     B)   After having set alien.spriteno to 10, we drop into the
first FOR...NEXT loop.  This does the following.

          Initially, it sets up a loop based on a variable we've
called row with an initial value equal to 10. Then immediately
after this, it sets up another FOR...NEXT loop based on a
variable we've called col (Column) with an initial value of 30
(the first sprite on each row will be displayed in column 30).
Next, the program  creates the first alien sprite. It will be
sprite number 10 (that's the value that's in variable
"alien.spriteno" at this stage), character number 2 (our alien
definition), row 10 (that's the value in variable "row" at this
stage), and column 30 (that's the value in variable "col" at this
stage).

     C)   Now, we add 1 to the alien.spriteno (it now has a value
of 11) and do the NEXT col instruction. This tells Basic to go
back to the FOR col.. line, add 30 to the col value (30 is the
value we want to increment col by), which will now contain a
value of 60, and test if the value of col is greater than 300.
Since the value of col is not 300 yet, the program will drop down
to the commands following the FOR col.. line and create the next
alien.sprite. This will be sprite number 11 and be displayed at
row 10, col 60.

     D)   The program will continue to create alien sprites on
row 10 at ever increasing columns until the value of col is
greater than 300. When this happens, the program will cancel the
FOR col = . . . loop and drop down to the NEXT row command.

     E)   Now it will add 20 to row (the increment or step value)
making row equal to 30 (since it was previously 10), go back to
the FOR row = . . .  line, and test if row is greater than 50.
Since it isn't, it will drop down to the FOR col line and set up
a completely new loop based on col again with the variable col
initially set back to 30.

     F)   It will then create the alien sprites (10 of them) for
row 30, then do the same thing for row 50. After row 50, it will
cancel the FOR row = . . .  loop and drop down to the command
following the loops - all 30 of our alien sprites will have been
set up

     NOW RUN THIS PROGRAM.

     Watch the aliens come down the screen. Because we said "W"
(wrap) in the CREATE command, the aliens re-appear at the top
once they get to the bottom. The program will stop once the value
of variable J is greater than 2000.

NOTE: When sprites cross each other, you will notice that where
they cross, their colours change. This is a "feature" of QBasic
graphics and is NOT a problem with your GameBasic program.

5.7  GameBasic Variable   INKEY
_______________________________


Demo program GAME04.BAS

     Now retrieve program GAME04.BAS

     Here, we have introduced a GameBasic variable that you can
use in your programs. This is a numeric variable called INKEY.

     Each time the GameBasic CALL MOVE command is issued, it will
place into INKEY a number representing the last key that was
pressed on the keyboard since the last time that CALL MOVE was
issued.

     You will be using the keyboard to control your game (in
other words, when the player presses the space bar key, you may
want your program to fire a missile..) You can use the INKEY
variable to test which key was pressed and make your program take
appropriate action.

     As an example, the number representing the space bar is 32.
If no key was pressed, the value in INKEY will be zero (0).

Please refer to Appendix A for a full list of key values.

NOTE: For alphabetic keys A to Z, the INKEY variable will always
contain the value for the lower- case letter, even though the
Shift key may be on. This is a friendly feature so that you don't
have to test for upper-case and lower case keys in your program.

     In this program, we have written a DO WHILE loop around the
CALL MOVE command as follows:

               '***** Main program loop ************
               DO WHILE INKEY = 0
                    CALL MOVE
               LOOP
               END

     Now, when you run this program, the sprites will continue to
move until such time as any key is pressed on the keyboard. When
this happens, INKEY will NOT be zero and the DO WHILE loop will
terminate and the program will drop down to the END instruction.

     Press F5 (or ALT then R then S) to start this program
running. Watch what happens. Now when you want the program to
stop, press any key.

Great! We're starting to put together a neat game, eh? Can you
see it taking shape? Actually, this is how you will develop most
games, after you've flowcharted the logic - step by step - so you
get each section of your program working before you go on to the
next section.

Now we're going to get the Cannon to move across the bottom of
the screen by getting the player to press the direction keys <-
and  ->

Demo program GAME05.BAS

     Call up program GAME05.BAS.
     This is exactly the same as the previous program except for
two changes.

     Firstly, we've added another line - the CALL CONTROL line.
Can you see it?


5.8   CALL CONTROL (sprite.no, horiz$,  vert$,  pixspermove,
      "u", keyup,   charup,    shootdirectup,    shootcharup,
      "d", keydown, chardown, shootdirectdown, shootchardown,
      "l", keyleft,   charleft,   shootdirectleft, shootcharleft,
      "r", keyright, charright, shootdirectright, shootcharright)
_________________________________________________________________


  Example : CALL   CONTROL    (1,"Y","N",2,
                               "up",   0,   0,  0,  0,
                               "do",   0,   0,  0,  0,
                               "le",  75,   1,  0,  3,
                               "ri",   77,  1,  0,  3)

     This is a very powerful command, and hence has the most
number of parameters. However, don't despair - you probably only
need one of these in your program, unless you're programming a
two-player keyboard game.

     This command tells GAMEBASIC that a specific sprite number
is to be controlled by the keyboard. For that sprite number, it
also tells GameBasic whether the sprite can move horizontally
and/or vertically, the number of pixels it should move each time,
which keys control the sprite movement, the character the sprite
should be shown as when it's moving in a particular direction (ie
a spaceship pointing up the screen as opposed to pointing to the
left) and, when the SHOOT command is issued for this sprite (see
later), which character to shoot (ie a missile pointing up rather
than a missile pointing to the left) and in which direction it
should move.

If you were developing a game for two players to play at the same
time, like the TANK game in the Gamebasic demo program, you
simply code one CONTROL statement for each of the sprites you
want to have as keyboard-controlled sprites, telling Gamebasic
which keys control which sprite etc....


     sprite.no    -   a number from 1 to 90 representing the
                    Sprite to be controlled.

     horiz$       -   "Y" - the sprite can move horizontally.
                      "N" - the sprite can't move Horizontally.

     vert$        -   The same definitions as above for horiz$,
                    but controls whether the sprite can move
                    Vertically.

     pixspermove  -   This represents the number of pixels the
                    sprite should move each time a control key is
                    pressed. Enter a value of 1 to 100, where 1
                    is slow and progressive values are faster,
                    but jerkier. A reasonable range would be from
                    1 to 6.

     "U", "D", "L", "R" - These are string parameters that are
                    included to simplify reading the CALL CONTROL
                    line and have no effect in the program. You
                    can enter anything between the quotes - "UP",
                    "left" etc....

     keyup, keydown, keyright, keyleft -these parameters define
                    which keys, when pressed, move the sprite in
                    the specific direction. Enter the INKEY
                    number for the key (see Appendix A for
                    complete list of values). For example,

                         spacebar            =   32
                         Left arrow key      =   75
                         F12                 =  134
                         Right arrow key     =   77

     charup, chardown, charleft, charright - these parameters
                    tell GAMEBASIC which character to display the
                    sprite as when it is moving in a particular
                    direction. For example, if we had a
                    keyboard-controlled spaceship in the middle
                    of the screen, if it was moving to the left
                    you would probably want it to look different
                    than when it is moving in any other
                    direction. Remember to set up a char$ (see
                    above) for each orientation (ie up, down, ..)
                    of your sprite.

shootdirectup,shootdirectdown,shootdirectleft,shootdirectright
                       - when the SHOOT command is issued for
                    this sprite (see later), these parameters
                    tell GameBasic which direction to fire the
                    projectile in depending upon the direction
                    this sprite is facing.

shootcharup, shootchardown, shootcharleft, shootcharright -
                       - when the SHOOT command is issued for
                    this sprite (see later), these parameters
                    tell GAMEBASIC which character (char$) to use
                    for the projectile to be launched - you can
                    use a different character to "shoot" for each
                    different direction in which your sprite
                    moves.


     Now look at the GAME05.BAS program again.
     The other change we've made to this program is to the DO
WHILE instruction. Instead of coding

               DO WHILE inkey = 0
          we've changed it to say
               DO WHILE inkey <> 101

     Do you know why? The answer is that in this program, you'll
be pressing left and right arrow keys to move the cannon across
the bottom of the screen, so as soon as you press one of these
keys, inkey will not be 0. If we didn't change this DO WHILE
instruction, then as soon as you pressed any key, the program
would stop. We've changed the instruction to stop when the "E"
key is pressed (INKEY number 101). The MOVE loop will continue as
long as inkey is not equal to number 101 (the E key).

     Now press F5 (or ALT then R then S) to run this program.

     Watch the cannon move across the bottom of the screen when
you hold down the left and right arrow keys!

     If you look at the CALL CONTROL command in the program,
you'll notice that we have not entered any values for the
parameters following the keyleft or keyright parameters. Neither
have we entered any values for the keyup or keydown parameters
(or the parameters following them). At this stage in the
development of our game, our cannon sprite can only move to the
left or right - it can't fire anything. Also, we haven't used the
SHOOT command yet, so we don't need any of the parameters that
follow the keyup, keydown parameters. (We'll get into the SHOOT
command later).

     So, now we have our aliens invading us coming down the
screen, and we have our cannon at the bottom of the screen and we
can move it from left to right.

     Now, wouldn't it be nice if we could fire a missile and
knock those aliens out of the sky?

     Well, first things first. Lets get our cannon to fire a
missile when we press the space bar.

Demo program GAME06.BAS

     Call up program GAME06.BAS.
     This program builds upon the previous program.
     Here, we've added a few lines in our main program loop to
fire a missile when the space bar is pressed.

             next.missile.no = 40
             '****** main program loop ***********
             DO WHILE inkey <> 101
                    CALL MOVE
                    '  Test if spacebar pressed and we have to
                              fire a missile
                    IF inkey = 32 THEN
                              CALL SHOOT(next.missile.no, 3, 1,
                                        0, 40, 7, "D", "D")
                            next.missile.no = next.missile.no+1
                              IF next.missile.no > 44 THEN
                              next.missile.no = 40
                    ENDIF
             LOOP

     Firstly, we're going to allow 5 missiles to be in-flight at
the same time, using sprite numbers 40 to 44. (Remember that
we've numbered our 30 aliens from sprite numbers 10 to 39). To do
this, we set up a variable called next.missile.no before we go
into our main program loop, and give it a value of 40. After
we've fired a missile, we add 1 to this variable. So, after we've
fired our first missile, it will have a value of 41. We use this
variable to represent the sprite number in the CALL SHOOT
command. When the value of next.missile.no gets to be greater
than 44, we re-set it to 40. Neat, huh?


5.9   CALL SHOOT (sprite.no, charno, from.spriteno, to.spriteno,
speed, pixspermove, horiz$, vert$)
________________________________________________________________

     Example:
     CALL SHOOT(40, 3, 1, 0, 40, 7, "D", "D")

     When this command is issued, a sprite is created using the
character definition referenced by charno, starting at the
location of the sprite referenced in from.spriteno aimed towards
the sprite referenced in to.spriteno at the given speed and
pixelspermove. If the from.spriteno is a keyboard-controlled
sprite (like a cannon) and to.sprite is entered as 0 (zero), then
the direction for the shoot sprite to move in will be taken from
the CALL CONTROL parameters coded.

     sprite.no  -   A number from 1 to 90 representing the
                    sprite to be created for this projectile.

     charno     -   the character number for this sprite (see
                    char$). If the from.spriteno parameter that
                    follows is one that is controlled by the
                    keyboard, then the shootchar value in the
                    CALL CONTROL command will override this
                    character number.

     from.spriteno -  the sprite number which is firing this
                    projectile.

     to.spriteno  -  the sprite number to which this projectile
                    should be aimed. If 0 (zero) is coded and the
                    from.spriteno is one that is controlled by
                    the keyboard, then the direction is taken
                    from the CALL CONTROL parameters for that
                    sprite.

     speed     -   the speed the sprite should start moving at,
                    from 0 to 40.
                    0 represents a sprite that doesn't move
                    (until you change its speed with a CALL
                    MOTION command, as described later).
                    1 is slow;   40 is fast.

     pixspermove  -  the number of screen pixels that this sprite
                    should move. This value is normally from 1 to
                    6. A low value will produce a smooth-moving
                    (but slower) sprite. A higher value will give
                    a faster moving sprite but its motion may
                    appear more jerky!

     horiz$/vert$   - defines what happens to the shoot sprite
                    when it meets a screen border, as in previous
                    commands above.

     Before we run this program, notice the changes that we've
also made to the CALL CONTROL command. We've changed the
parameters to specify which character to use as a missile when
the SHOOT command is issued and the cannon is moving either left
or right. (the shootcharleft and shootcharright parameters are
both coded as 3 - the definition for a missile going up - since
we want to fire a missile directly upwards (zero degrees)
regardless of whether the cannon is moving to the left or to the
right).

     Now, press F5 (or ALT then R then S) to run the program.
When the program starts, move the cannon with the left and right
arrow keys to position the cannon below a alien - then press the
space bar. You should see a missile launched from the canon
directly upwards. (You can press 'E' to stop the program).

     When the missile gets to the top of the screen, it's
deleted. That's good, right?

But what happens when the missile actually hits one of the
aliens? NOTHING! It goes right through it!      That's because we
haven't added any code in our program to test to see if any of
our missiles have hit any of the aliens. That's going to be our
next exercise.

Demo program GAME07.BAS

     Retrieve program GAME07.BAS
     This program is the same as the previous one, except we've
added some more code to the main body of our DO WHILE loop.

               'Test if any missiles have hit any aliens
               FOR missile.no = 40 to 44
                    CALL ACTIVE(missile.no, 0, missile.active)
                    IF missile.active = 1 THEN
                         CALL CHECKHIT(missile.no, 10, 39, 8,
                                   alien.no)
                         IF alien.no > 0 THEN
                              CALL DELETE(missile.no, 0)
                              CALL DELETE(alien.no, 0)
                         END IF
                    END IF
               NEXT missile.no

     This code is doing the following:

     For each of our five possible missiles that we can launch
(controlled by the FOR missile = 40 to 44 loop) we're checking to
see if the missile is actually active (in other words, it's been
fired and has not yet hit an alien or got to the top of the
screen) If it IS active, then we check if it has hit an alien! If
it has hit an alien, we delete the alien and the missile, then go
back and do the same process for the next missile until we've
checked all missiles.

     The above code introduces us to three new GameBasic
commands, which we'll explain one at a time:


5.10  CALL  ACTIVE ( sprite.no1, sprite.no2, return-value)
__________________________________________________________

     Example:
     CALL ACTIVE (40, 0, num.active)

     This is a GameBasic command that will tell us whether one or
more sprites are currently active on the screen.

     sprite.no1 -   enter a number from 1 to 90 representing the
                    first sprite number you wish to check for.

     sprite.no2 -   if you wish to check for a range of sprites
                    (ie from numbers 20 to 40), then enter the
                    last sprite number you wish to check here. If
                    you enter 0 (zero) as this parameter, the
                    routine will only check for sprite.no1.

     return-value - You should enter a numeric variable name to
                    receive the value returned. What will be
                    placed in this variable after the routine has
                    been called will be the total number of
                    active sprites in the range defined.

     In the program GAME07.BAS, we've substituted the numeric
variable missile.no for sprite.no1 and the other numeric variable
missile.active for the return-value. Sprite.no2 is coded as 0
(zero) since we don't want to check for a range of sprite
numbers, just for one specific missile.

     Now you might say, "Why not check for all missiles using
this one command"?. If we did that, then all we would get back
from the CALL ACTIVE command might be the value of 2 in
missile.active - in other words, we would find out that there are
two missiles active, but we wouldn't know which ones they were.
For what we want to do at this stage in the program, that would
be of little help. We need to execute the code following the CALL
ACTIVE only for active missiles, and we need to know the missile
number each time we execute the code. That's why we've set up a
FOR ... NEXT loop based on missile.no


5.11  CALL  CHECKHIT (  sprite.no,   target.sprite1,
                    target.sprite2, tolerance, return-value)
_____________________________________________________________

     Example:
     CALL CHECKHIT ( missile.no, 10, 39, 8, alien.no)


     This is the GameBasic command which tells us if a specific
sprite has collided with any other sprites in our game (ie has a
missile hit an alien?). Non-moving sprites, like rocks or land
mines, will be checked if they fall within the sprite number
range you specify. Non-active sprites (ie sprites that have
previously been deleted) will be ignored.

     sprite.no,  target.sprite1,  target.sprite2 -
                    There are three options to this command which
                    are controlled by the presence or absence of
                    values in target.sprite1 and target.sprite2.
                    You can check 1 to 1,  1 to ALL,  and 1 to
                    Range.

                         1 to 1 :      checks if one specific
                              sprite has hit one other specific
                              sprite. Enter sprite.no and
                              target.sprite1.  (target.sprite2
                              must be 0.)

                         1 to ALL :   checks if one specific
                              sprite has hit ANY OTHER active
                              sprite. Enter sprite.no.
                              (target.sprite1 and target.sprite2
                              must be 0.)

                         1 to Range : checks if sprite.no has hit
                              any of the sprites in the range
                              between target.sprite1 and
                              target.sprite2, which must both be
                              entered.

     tolerance  -     Enter a numeric value which represents the
                    accuracy of the  check you want. Distance
                    between two sprites is measured from both
                    sprites top left current positions. If a low
                    number is entered for tolerance (for example,
                    4), then the sprites will have to be very
                    close to each other to register a "hit". If a
                    larger number is entered (ie above 10 ..),
                    then a hit may be registered although it may
                    appear on the screen that the sprites are not
                    touching.

     return-value  - enter a variable name here. The routine will
                    put into this variable the first sprite
                    number in the target sprite range that has
                    registered a hit. If no sprites register a
                    hit, the value is zero.

     In our program GAME07.BAS, we're checking to see if the
current missile (missile.no) has hit any of the alien sprites
(sprite numbers 10 to 39) so we're using the Range option. What
we get back in the variable alien.no after issuing this command
is either 0 (which means that this missile hasn't hit an alien)
or the sprite number of the alien that the missile has hit.

     So, if alien.no is greater than 0, we know that we've hit an
alien, and we have the alien's sprite number in the variable
alien.no (which was returned to our program by the CALL CHECKHIT
routine). We can then use the variable alien.no to delete the
alien, which brings us nicely into the next subject:


5.12  CALL   DELETE  (sprite.no1, sprite.no2)
____________________________________________


     Example:
     CALL DELETE (10,  0)

     We use this GameBasic command to delete active sprites.

     sprite.no1   - enter the first sprite number you wish to
                    delete.

     sprite.no2  -  if you wish to delete a range of sprites,
                    then enter the last sprite number in the
                    range you wish to delete. This parameter must
                    be present. If you only want to delete one
                    sprite, then enter 0 for this value.


     In our program above, we CALL DELETE to delete the alien
sprite when it's been hit by a missile (it's sprite number is in
the variable alien.no which we pass to the CALL DELETE routine)
and also to delete the missile (it's sprite number is the value
that's currently in the variable missile.no).

     Now, run this program by pressing F5 (or ALT then R then S).
Now, move the cannon under a alien and press the space bar.

     You should get a missile going up and, if your aim is good,
when the missile hits an alien both the alien and the missile
will be deleted. Practice changing the tolerance value in the
CHECKHIT command to see when it registers a hit and when it
doesn't.

     When you're happy that you follow the above, then "Read on,
McDuff!" (with apologies to Shakespeare).

     We're nearly getting to the end of programming our first
complete game. Just a few more things to do.

     If you don't hit all the aliens before they reach the bottom
of the screen, what happens?   Nothing!  It would be a good idea
to add some code to stop the game and display a message like "Ha,
ha! We've landed - you lose!"

     Also, if you're a really good shot, and you hit all the
aliens before any one of them gets to the bottom of the screen -
nothing happens!. Again, we should add some code to handle this
condition - maybe displaying a message like "You got us! Well
done!"


 Demo program GAME08.BAS

     Retrieve program GAME08.BAS
     This program builds on the previous program (as you probably
guessed).

     Firstly, we've changed the main DO WHILE inkey <> 101 loop
that keeps the game going as follows:

               end.of.game$ = "N"
               DO WHILE end.of.game$ = "N"
                         CALL MOVE
                         .
                         .   program commands...
                         .
                         .
               LOOP

     What this does is let us control when the game ends. The
game can end when a number of situations happen. One such
situation is when we've hit all the aliens. Another is when an
alien lands (reaches the bottom of the screen).

     When these situations occur, all we do is move "Y" to the
variable end.of.game$ and this will stop the DO WHILE loop since
end.of.game$ is not "N" any more.

     The first line sets end.of.game$ to "N". If we didn't set
end.of.game$ equal to "N" before we go into the DO WHILE loop,
we'd drop right through the program and stop immediately.


     Here's the code we've added to test if a alien has reached
the bottom of the screen:

             FOR alien.no = 10 to 39
                    CALL INFO(alien.no, row, col, s, d, c, d$, p)
                    IF row >= 180 THEN
                         end.of.game$ = "Y"
                         DO WHILE ip$ <> "M"
                              CLS
                              LOCATE 10, 5
                              PRINT "We've landed - you lose"
                              INPUT "Press M to continue", ip$
                              ip$ = UCASE$(ip$)
                         LOOP
                    END IF
               NEXT alien.no

     Before we explain the CALL INFO command, let's discuss what
the above code is doing. First, we set up a FOR ... NEXT loop to
process each alien sprite in turn. For each alien sprite, we test
to see if it has reached row 180 (by using the CALL INFO command
to get it's current row). If it has, we set the variable
end.of.game$ to "Y" (to stop the main DO WHILE loop next time
through and make the program go to the end) then we clear the
screen and print a message. Finally, we set up a DO WHILE loop
continually asking the player to press M to continue. Unless the
player presses M, the program will do nothing else.

     Why do we do this?  Well, it's for safety while you're
developing your game. You'll find that when you're playing your
game to test how it runs, you'll be pressing the direction and
spacebar keys so quickly that you may not notice that the program
ended. When the program ends, Basic displays it's regular "Press
any key to continue" line and then passes you straight back to
your program in edit mode. If you don't put a pause in somewhere,
you could end up with some of the keys you were pressing in your
game being written to your program code unexpectedly. Adding this
code above forces the player to hit a specific key (which should
not, obviously, be a key you're using in your game) to get back
to the program edit screen.

     (NOTE: An easier way of doing this is to use the GameBasic
TEXTSCREEN routine described later)

     Now lets explain the CALL INFO command. It's very easy.



5.13  CALL  INFO ( sprite.no, col, row, speed, direction,
                        char.no,  hit.edge$, pixspermove)
_________________________________________________________


     Example:
     CALL INFO ( 1,  c,  r,  spd,  direct,  character, edge$, p )

     This GameBasic command will return information on a specific
sprite.

     sprite.no - Enter the number of the sprite for which you
                    want information.

     col  -    Enter a numeric variable name into which the
               routine will place the sprite's current column.

     row  -    Enter a numeric variable name into which the
               routine will place the sprite's current row.

     speed  -   Enter a numeric variable name into which the
               routine will place the sprite's current speed.

     direction - Enter a numeric variable name into which the
               routine will place the sprite's current direction.
               The value will be an angle measured in degrees
               from the top of the screen clockwise; as was
               discussed in the CALL CREATE command.

     char.no - Enter a numeric variable name into which the
               routine will place the sprite's current character
               number that it is being displayed as.

     hit.edge$- Enter a string variable name into which the
               routine will place the following information.

                              "T" - sprite has just hit the top
                                   of the screen.
                              "B" - sprite has just hit the
                                   bottom of the screen.
                              "L" - sprite has just hit the left
                                   edge of the screen
                              "R" - sprite has just hit the right
                                   edge of the screen.


     pixspermove  - Enter a numeric variable into which the
               routine will place the number of pixels this
               sprite currently moves each time.



     Now look at the code we added to this program to check
whether we've hit all the aliens. It's very similar to the code
checking if an alien has landed.

               'test to see if we've hit all the aliens
               CALL ACTIVE ( 10, 39, aliens.left )
               IF aliens.left = 0 THEN
                    end.of.game$ = "Y"
                    CLS
                    DO WHILE ip$ <> "M"
                        PRINT "Good shooting - you got us all"
                                 .
                                 .
                    LOOP
               END IF

     Here, we're using the CALL ACTIVE command to test for a
range. The range is from 10 to 39, which represents all the alien
sprites we set up. If none of them are active, we've just hit the
last one!

     Now run the program and see what happens.
     Press F5 (or ALT then R then S).

     Now we're getting there. But it's pretty easy to get them
all, isn't it. Let's try and make it a bit more difficult. We're
going to do two things with the next version of our program.
Firstly, we'll get the aliens to shoot a fireball straight down
at the cannon and add some code to test if the cannon's been hit
- if it has we'll stop the program.

     Then, we'll change the program to make it necessary to hit
an alien twice before it gets deleted. We'll use the CALL
CHANGECHAR command to change the aliens character after the first
hit.

Demo program GAME09.BAS

     Retrieve program GAME09.BAS
     This program builds on the previous one (as if you didn't
know!).

     Firstly, we've defined a new character in char$ (4,..) to
represent an alien fireball and also we've added a section of
code in the main program loop to test whether there is an alien
fireball active. If there isn't, we'll create a fireball going
straight down. Also, we'll test to see if the fireball has hit
the cannon. Here's the code to create the fireball:




               'test if fireball active
               CALL ACTIVE ( 4,  0,  fireball.active )
               IF fireball.active = 0 THEN
                    CALL RAND ( 10,  39,  random.alien )
                    CALL ACTIVE ( random.alien,  0, alien.active)
                    IF alien.active = 1 THEN
                      CALL INFO (random.alien,col,row,s,d,c,e$,p)
                      CALL CREATE (4,4,row,col,40,5,
                                   180, "D", "D"," ")
                    END IF
               END IF

     First, we're checking if sprite number 4 (the sprite number
we're assigning to a fireball) is active at the moment. In other
words, if there's already a fireball on the screen, don't create
another one. If there is no fireball active (ie fireball.active =
0) then we use the GameBasic CALL RAND command (which will be
explained next) to get a random number between 10 and 39 to
represent the firing alien. If the firing alien that we come up
with is active, we get it's row and column location and then
create a fireball sprite coming directly down from that location.
(It would seem strange if a deleted alien could still fire a
fireball but I guess it could if it was "cloaked" like the
Clingons!. However, in our program at the moment, it can't).

 Here's the code to test if the fireball has hit our cannon:
(note that our cannon is sprite number 1 and the fireball is
number 4)

          'test if fireball has hit our cannon
          CALL CHECKHIT (1,  4,  0,  6,  hit )
          IF HIT > 0 THEN
               end.of.game$ = "Y"
               DO WHILE ip$ <> "M"
                    CLS
                    LOCATE 10,5
                    PRINT "We hit your cannon - you're dead!"

                    INPUT "Press M to continue"; ip$
                    ip$ = ucase$(ip$)
               LOOP
          END IF


5.14   CALL   RAND  ( rand1,  rand2, return-value )
___________________________________________________

     Example:
     CALL RAND ( 10,  39,  alien.no )

     The CALL RAND GameBasic routine will return in the variable
entered for return-value, a random number between the two numbers
entered in rand1 and rand2. You will use Random numbers quite a
lot in your games.

     As you can see in our program GAME09.BAS, we used CALL RAND
to give us a random number between 10 and 39 (our alien sprite
numbers) to select a random alien to fire a fireball.

     Now, we'll explain the code we added to make it necessary to
hit the alien twice before it gets deleted. First, we added a new
character definition, char$ ( 5 , n ), to define a different
coloured alien. We'll use this new character definition when we
first hit the alien.

               'Test if any missiles have hit any aliens
               FOR missile.no = 40 to 44
                    CALL ACTIVE(missile.no, 0, missile.active)
                    IF missile.active = 1 THEN
                         CALL CHECKHIT(missile.no, 10, 39, 8,
                                        alien.no)
                         IF alien.no > 0 THEN
                              CALL INFO(alien.no, row, col,
                              speed,direction,charno,edge$,pixs)
                              IF charno = 2 THEN
                                   CALL CHANGECHAR(alien.no, 5)
                                   CALL DELETE(missile.no, 0)
                                 ELSE
                                   CALL DELETE(missile.no, 0)
                                   CALL DELETE(alien.no, 0)
                              END IF
                         END IF
                    END IF
               NEXT missile


     In the above, when we've hit an alien, the first thing we do
is CALL INFO. This command will return information to us about
the sprite in question. What we're after here is the character
number it is currently being displayed as. If it's being
displayed as character number 2 (the regular alien sprite) then
we CALL CHANGECHAR to change its character number to character 5
(a different coloured alien sprite). If it's not character number
2, then it must be character number 5, so we delete it. Notice in
all the code above, where we have used what we call NESTED IF's,
that we always line up the END IF command with the associated IF
statement to make our program clearer to read.


5.15  CALL  CHANGECHAR ( sprite.no,  char.no )
______________________________________________

     Example:
     CALL CHANGECHAR ( 1,  5 )

     This GameBasic command lets you change the character that
the sprite is currently being displayed as.

     Sprite.no   - enter the number of the sprite who's character
                    you wish to change.

     char.no     - enter the new character number for the sprite.

     In our program above, we use this command to change the
alien's character from character 2 (the regular character) to
character 5 after it has been hit once.

     Now run this program by pressing F5 (or ALT then R then S).


That's it. You've now completed your first game in GameBasic.

WELL DONE.

You can use what you've learnt to make your own games very
easily.

Make a copy of this last program, and see if you can change it so
that when all the aliens have been shot, the program goes back to
the beginning, recreates the alien sprites etc... and plays
again, but at a faster speed.

See if you can add a SCORE process that adds up number of aliens
hit and displays the score on the screen. How about making the
alien speeds random,  or. . . ,   or . . , or . . .

The possibilities are endless.


HAVE FUN.   That's what it's all about!
(Have a look at program GAME10.BAS !)


___________________________________

6.   ADDITIONAL GAMEBASIC COMMANDS.
___________________________________

     The following are additional Gamebasic commands that have
not been covered up to this point.


6.1  CALL MOTION (sprite.no,speed,direction, pixspermove)
_________________________________________________________

     EXAMPLE:
     CALL MOTION (1,  35,  270, -1)

     This command changes a sprite's speed and direction.

     sprite.no   -    enter the number of the sprite you wish
                      to change.

     speed      -     enter the revised speed for this sprite.

     direction  -     enter the revised direction (angle) for
                      this sprite.

     pixspermove -    enter the revised pixels per move for this
                      sprite.

     Enter the value of -1 for any parameter which you don't want
to change. In the above example, we're changing speed and
direction, but not the sprite's pixels per move.


6.2  CALL GETANGLE ( sprite.no1, sprite.no2,  return-value)
__________________________________________________________


     EXAMPLE:
     CALL GETANGLE  ( 1,  2,  new.angle)

     This command will return the angle between two sprites.

     sprite.no1    -      enter the first sprite number.

     sprite.no2    -      enter the second sprite number.

     return-value  -      enter a variable name to receive the
                          value for 'angle'


6.3  CALL MUSIC  (type$, length$, tempo$, octave$, notes$)
__________________________________________________________


     EXAMPLE:
     CALL MUSIC (  "C" , "L64" , "T255" , "O3" , "ABCDE" )

     Introduce a new dimension to your games by adding music and
sounds. All the following parameters are string parameters and
must therefore be enclosed in quotes (" "). For more details
regarding parameter options, please refer to the PLAY instruction
in Basic HELP.

     type$     -    There are two types of sounds you can create;
                    one is continuous and will play all the time
                    the game is playing. The other is a single
                    sound (like a missile launching), and will
                    interrupt a continuous sound.
                         "C" = Continuous
                         "S" = Single sound.

     length$ -      The length of each note's duration. Keep the
                    lengths as short as possible (ie high values)
                    otherwise the music will impact the game's
                    speed.

                       "Lnn" where nn is the length; from 1 to 64

     tempo$ -       The tempo of the music (the number of quarter
                    notes per minute. Keep this as a reasonably
                    high value to minimise impact to your game's
                    speed.

                     "Tnn" where nn is the tempo; from 32 to 255.

     octave$ -      The octave the notes should initially start at.
                    "On" where the O is the letter "Oh" and n is
                    from 0 to 6.

     notes$ -       The actual notes you want to play;  ie
                    "ABBD>ACF"
                    Including a ">" or "<" sign in the notes will
                    increase or decrease the octave of following
                    notes.

HINT: If you have coded music and you want to turn it off
(perhaps your dad's sleeping again!) then use the GameBasic
variable gb.music$. Setting this to "N" at the top of your
program will turn the music off. Setting it to "Y" will turn
music on.




6.4 CALL TEXTSCREEN (Screen.mode,Clear.screen$,Choice$)
_______________________________________________________


     EXAMPLE:
     CALL TEXTSCREEN ( 2, "Y", play.again$ )

     Use this GameBasic routine to display a menu or text screen
from which the player will select a choice.

     The routine uses a GameBasic array called gb.line$() which
has 25 entries, each entry representing the text that you want
printed at that line number. Before calling TEXTSCREEN, enter all
the valid keys that the user can press into the variable you will
be passing to the routine. The routine will then check that a
valid key was pressed  before returning back to your program.
Note in our example above that if play.again$ has a null value
(""), or you code CALL TEXTSCREEN(1, "Y", "") then the routine
will accept ANY key as a valid key.

     Screen.mode - Enter the screen mode that you want the text
                    screen to be displayed in. (See Chapter 7.1
                    for a full discussion on Screen Modes).
                    Valid values:  1  or 2

                      Note: If you select a screen mode that is
                    different than the one your game is currently
                    using, your game screen will be wiped-out
                    when the text screen is displayed.

     Clear.screen$ - Enter a value of "Y" or "N" to specify
                    whether you want the current screen to be
                    cleared before the text  screen is displayed.

     Choice$ -       Enter all the valid keys that the player can
                    enter in response to your text screen. An
                    entry of null ( "" ) will accept any key as a
                    valid key.

     An example might be:
               gb.line$(1) = "                  My Game  Menu "
               gb.line$(2) = "                   ------------- "
               gb.line$(5) = " N - Novice   Level"
               gb.line$(6) = " A - Advanced Level"
               gb.line$(7) = " E - Expert   Level"
               gb.line$(9) = " X - Exit"
               level$ = "NAEX"
               CALL TEXTSCREEN( 2, "Y", level$)
               IF level$ = "N" THEN .......


     Another example might be:
               gb.line$(15) = "Well done.You have won the Game. "
               gb.line$(17) = "Play again?  Y or N : "
               continue$ = "YN"
               CALL TEXTSCREEN( 1, "N", continue$)
               IF continue$ = "Y" THEN ......
               IF continue$ = "N" THEN .......


6.5  CALL QUESTION (Question.row,  Question.col,
                                   Answer.row,  Answer.col,
                                   Question.no, Result$)
_____________________________________________________________


     Example:
     CALL QUESTION ( 10, 1, 15, 1, q.no,  ans$ )

     Gamebasic lets you create question and answer games very
easily, also incorporating animated characters to enhance your
game. To make such games, you enter your questions into an array
called gb.question$, and the correct answer into an array called
gb.answer$, then issue the CALL QUESTION command.

     NOTE: BEFORE YOU START YOUR GAME, OR WHEN YOU RE-START IT,
SET THE GAMEBASIC VARIABLE GB.QUEST.OS (QUESTION OUTSTANDING) TO
0.

     Question.row  -  This is the row at which the question will
                      print and can be from 1 to 25.

     Question.col  -  This is the column at which the question
                      will print and can be from 1 to 79.

     Answer.row   -   The row where the answer that the player
                      keys in will be printed. Valid values are
                      from 1 to 25.

     Answer.col   -   The column  where the answer that the
                      player keys in will be printed. Valid values
                      are from 1 to 79.

     Question.no   -  The question number that is to be asked. You
                      can enter up to 300 questions and answers.

     Result$   -      The routine returns one of three values:
                      space - the question is still being
                      answered,player has not yet hit enter.

                    "Y"   - The player entered the correct answer
                    "N"   - The player entered the wrong answer

     The following example will illustrate:

           gb.question$(1) = "What is the capital of France?"
           gb.answer$(1)   = "Paris"
           gb.question$(2) = "What is the longest river in Africa?"
           gb.answer$(2)   = "Nile"
           gb.question$(3) = "What is the population of Canada?|
                                a) 2  million |  b) 320 million |
                                c) 28 million"
           gb.answer$(3)   = "C 28"
           end.of.game$    = "N"
           quest.no = 1
               DO WHILE end.of.game$ = "N"
                     CALL MOVE
                     CALL QUESTION(10, 5, 20, 5, quest.no,ans$)
                     IF ans$ = "Y" THEN
                           PRINT "That's right"
                           quest.no = quest.no + 1
                           score = score + 1
                      ENDIF
                      IF answer$ = "N" then .......
                .
                LOOP

          Notice the character "|" in gb.question$(3) above? This
is the character above the "\" on your keyboard. Each time this
character is encountered while the question is being printed,
printing will start on a new line. This question would therefore
appear on the screen as follows:

               What is the population of Canada?
               a) 2 million
               b) 320 million
               c) 28 million?

          If you want to include a quotation mark in your
question, use the single quotation mark - '


          The fact that Result$ can contain a space needs a bit
of explanation. With this function, you can have animated
characters moving around on the screen while the question is
being answered - for example, you could have a runner at the top
of the screen running towards a series of hurdles. The longer the
player takes to answer the question, the closer the runner would
get to the first hurdle. If the question isn't answered correctly
by the time the runner reaches the first hurdle, your program
could make the runner fall down rather than jumping the hurdle.
To do this, you have to have the CALL QUESTION line as part of
your main program loop, which includes the CALL MOVE routine
(which moves the runner) as follows:

                    end.of.game$ = "N"
                    CALL CREATE ( 1, 1, 10, 20, ... . )  'code to
                                                    create runner
                    CALL CREATE ( 2, 2, 10, 60, ..... )  ' and
                                                          hurdles
                    . . .
                    DO WHILE end.of.game$ = "N"
                         CALL MOVE
                         CALL RAND ( 1, 100, quest.no )
                         CALL QUESTION ( 10, 5, 20, 5, quest.no,
                                                  ans$ )
                         IF ans$ = "Y" THEN ......
                         IF ans$ = "N" THEN ......
                         ' code to test if runner has reached
                              next hurdle etc....
                    . . . .
                    LOOP

     Even though CALL QUESTION is called each time the loop is
executed, if a question is still outstanding (ie the "Enter" key
has not been pressed) then nothing will happen and the next
question will not be asked. However, the CALL MOVE routine will
move the runner while the player is entering the answer to the
question. Make sure that your program only asks a new question
(adding 1 to quest.no) only when the parameter returned by CALL
QUESTION (ans$ in the example above) is either "Y" or "N". See
the demo program GBDEMO.BAS for an example of how this works.

NOTE: Before a new question is asked, the QUESTION routine will
automatically clear the screen from the row location of the last
question asked to the bottom of the screen. Therefore, if you
have graphics on the screen in this area, they will be erased.
Also, if you print the answer above the question, it will not get
cleared. Try to keep animation to the top of the screen and
questions and answers towards the bottom.




6.6  CALL TRACK  (Row.or.Col$, start.row.or.col.no, start.no,
                    end.no, width, track$)
_____________________________________________________________


     Example
     CALL TRACK( "R", 10, 30,  200, 2, "A" )

     With Gamebasic, you can make sprites follow one of 7 tracks
(tracks A to F - corresponding to colour codes A to F;  and track
0 - the background track) that you can lay down on the screen by
using this TRACK routine.

     If you want a sprite to follow a track then the CALL CREATE
command which creates the sprite must specify which track it is
to follow.

     Tracks can have intersections so that when a sprite
following a track comes to a junction, it will randomly decide
which path to follow.

     The following 2 tracks explain this:


                         bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
                         b                              b
aaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa       b
          a              b      a        a              b
          a              b      a        a              b
          a         aaaaabaaaaaaaaaaaaaaaa              b
          a         a    b      a                       b
          a         a    b      a                       b
          aaaaaaaaaaaabbbbbbbbbaa                       b
                      b       b                         b
                      b       bbbbbbbbbbbbbbbbbbbbbbbbbbb
                      bbbbbbbbb


     Each section of track you want to lay down has to be done
using the CALL TRACK routine as follows:

     Row.or.col$ -  This is a string parameter which tells
                    Gamebasic whether you are laying down a
                    vertical section of track (ie a Column) or a
                    horizontal section (ie a Row) Valid values
                    are "C" and "R".

     Start.row.or.col.no - This tells Gamebasic the starting Row
                    or Column number for this section of track.

     Start.no    -  If this is laying down a Row track, then
                    this parameter is the starting column number
                    the track should be laid from, otherwise it
                    is the starting Row number.

     End.no     -   This is the column or row that the track should
                    end at.

     Width      -   This is the width of track that should be
                    laid.

     Track$     -   The track letter that is assigned to this
                    track.
                         Valid values are "0" and "A" to "F".


     Let's take an example; look at the first line of Track B in
the diagram above. Assuming this line is at row 3, and the b's
start in column 60 and end in column 200 then if we wanted to
draw a track 1 pixel wide we would code:

               CALL TRACK ( "R",  3,  60,  200,  2,  "B" )

     In the CALL CREATE command for sprites you want to follow
track B, you must make sure that their initial row and column
position is on the track.

     Get the idea? Not too difficult is it?

     However, there are a few aspects you should be aware of in
laying down tracks and initially placing sprites on tracks:

          A).  If you are laying down multiple track numbers,
always lay down the lowest track number first, followed by the
next lowest after that one, and so on.

          B).  A sprite that is following track B (for example),
can also take any higher track if it's upper-left pixel meets
that track number in its travels. A sprite following track E,
(say) can only follow tracks E and F (if it exists), it can't
follow any lower tracks. Sprites following track 0 can only
follow track 0 and no higher track numbers.

          C). You only need to draw a track that is one pixel
wide for the sprite to follow it. You can give different tracks
different colours on the screen (see the CALL COLOUR command
later). You can also make the width wider than one pixel, BUT THE
WIDTH MUST NOT EXCEED THE NUMBER OF PIXELS THAT THE SPRITE MOVES
EACH TIME (as defined in the CALL CREATE command when the sprite
was set up)  OTHERWISE IT WILL SPEND MUCH OF ITS TIME MOVING FROM
ONE SIDE OF THE TRACK TO THE OTHER RATHER THAN MOVING ALONG THE
TRACK.

          D).  The initial positioning of the sprite you want to
move along the track and the distance between intersections is
very important. When you first create the sprite, if you don't
put it on the track you have laid down, it will not move at all -
it will just stay where it is flickering! The poor thing can't go
anywhere since it's not on the track.

          E).  This next issue is slightly more complex, so let's
take an example;

               Let's suppose we have laid down a track as
follows:

               aaaaaaaaaaaaaaaaaaaaaaaaaaa
               a         a
               a         a

               This is a pretty simple track. The row of 'a's
start in row 1 and the vertical 'a's start in column 5 and 15.
Now, if we created our sprite to move 4 pixels per move and
initially placed it at row 1 column 3, it would never take the
first vertical branch. However, it would take the second branch,
since it is defined a multiple of 4 pixels from the initial
sprite starting position (col 3 +(4 pixels * 3 moves) = 15).


          F).  Leave the top left screen dot (or pixel) in your
character definition for all your track sprites blank and try to
ensure (through your track layout and the number of pixels that
your sprites move) that in their travels, no sprite's top left
pixel coincides with any other sprite's non-blank pixel.


     HINT: Plan out your tracks, their numbers and intersections
carefully before you start programming. If a sprite doesn't move
when you put it on a track, you've probably not put it on the
track correctly. If it never takes an intersection, it's probably
missed it due to the above.




6.7  CALL COLOUR (Colour.code$, colour.name$, blue, green, red )
___________________________________________________________

     Examples
     CALL COLOUR  ( "A", "dragon track",  20, 40, 10 )
     CALL COLOUR  ( "0",   "Background",   10, 10, 34 )

     You can select from any of 262,144 colours. Colours are
defined as a combination of blue, green and red intensities, with
intensity ranging from 0 to 63 for each colour (64 x 64 x 64 =
262,144).

     Tracks A to F use colour codes A to F. Therefore, if you are
using colour code A (for example) in one of your character
definitions, and you have also defined a track A, their colours
will be the same. Having said this, then each colour in your
character and/or track definitions (0 to 9 and A to F) can be
custom defined using this routine. For example, you may have used
the colour red (number code 4) in a spaceship character. If you
wanted to change the colour to a specific hue of red (or even
another colour entirely) then you could use this command to do
that. However, every other character that uses code 4 in its
definition will also have its colour changed.

Run program GBCOLOUR.BAS supplied with this program to see
examples of other colours available, along with the codes needed
to define them.

     Colour.code$  - This is the background (0 or space) or
                    track/colour number that you wish to custom
                    colour.

     Colour.name$ - This is for information and program
                    documentation only.

     Blue         - The value of the blue intensity for this
                    colour. Range is from 0 to 63

     Green        - The same as above, but for Green.

     Red          - The same as above, but for Red.

     HINT: Initially, when you lay down a track, you'll want to
see it clearly to verify that you've got it on the correct place.
However, when you run your game, you'll probably not want the
tracks to be shown.  Use this function to make tracks the same
colour as the background, so they'll 'disappear'.


6.8  CALL DISTANCE ( sprite.no1, sprite.no2, distance )
_______________________________________________________


     Example:
     CALL DISTANCE (1, alien.no, dist)

     The DISTANCE routine returns the distance in pixels between
two active sprites.

     sprite.no1 -   The first sprite number

     sprite.no2 -   The second sprite number.

     distance  -    A numeric variable into which Gamebasic will
                    return the value of the distance between the
                    two active sprites. If either one is
                    inactive, -1 is returned.


6.9  CALL PAUSE   ( number )
____________________________


     Example:
     CALL PAUSE  ( 5 )

     The PAUSE routine, as its name implies, pauses your program
for a number of seconds.  While your program is paused, nothing
will happen. However, if you press any key on the keyboard before
the pause-time has expired, your program will start up again. If
you want to stop your program until any key is pressed,
regardless of the time, then use 0 for the number.

     number  - Enter a pause duration in number of seconds.
                         Value must be from 0 to 32000


6.10 CALL COLOURRESET
_____________________


     Example:
     CALL COLOURRESET

     COLOURRESET resets all custom colours you have defined,
including the background colour (0) and text-colour (15),  back
to their original QBasic colours.


6.11 CALL MOVEBACK   ( sprite.no )
__________________________________

     Example:
     CALL MOVEBACK ( 10 )

     MOVEBACK moves a sprite back to its last screen position.
This command is used in the TANK game. When the program detects
that a tank is running into a tree, it uses the MOVEBACK command
to move the tank back to its last position before it moved into
the tree. If the sprite is not active, nothing will happen. You
can only move a sprite back ONE move, you can't move it back to
its position prior to its last position.

     sprite.no  -   Enter a valid sprite number, from 1 to 90.



6.12 CALL PIXELCOLOUR ( sprite.no, top.left, top.right,
                            bottom.left, bottom.right)
_______________________________________________________

     Example:
     CALL PIXELCOLOUR ( 12, tl, tr, bl, br )

     The PIXELCOLOUR routine returns the colour codes of the
pixels at the four extreme corners of the specified sprite on the
screen. If you don't define a sprite pixel colour in the extreme
corners of your character definition, (for example, the first
position in CHAR$(3,1) = "..." , the 16th position in CHAR$(3,1)
, the first position in CHAR$(3,12) = "..." and the 16th position
in CHAR$(3,12) ) then PIXELCOLOUR will return the colour code on
the screen at these locations.

     This command is used in the TANK demo game to provide a more
accurate check as to whether a tank has run into an oil-patch,
rather than using the CHECKHIT routine.

     Sprite.no - Enter the number of the sprite you want to
                    check.

     top.left, top.right, bottom.left, bottom.right - Enter
                    numeric variables into which the routine will
                    place the colour codes of the pixels on the
                    screen at the specified locations.



_____________________________________

7.   MISCELLANEOUS GAMEBASIC FEATURES
_____________________________________


7.1  GB.SCREEN
______________


     There are two screen-modes in GameBasic, both controlled by
the variable gb.screen. The variable has to be set for your
selected screen mode BEFORE you call the DEFINECHAR routine to
set up your characters.


          GB.SCREEN  = 1

     This is the mode you're already familiar with.      In this
mode, there are 200 pixels down the screen (from 0 to 199) and
320 pixels across the screen (0 to 319). However, all row and
column parameters you enter in your Gamebasic CALL's must not be
greater than 187 and 303 respectively.

     This mode lets you create characters 16 pixels wide and 12
pixels deep, as explained in section 5.3 CHAR$. The definition
you're able to get to your characters is limited by the fact that
you only have 192 pixels to work with for each character.


          GB.SCREEN = 2

     In this mode, each individual pixel on the screen is smaller
than in mode 1 above. There are 480 pixels down the screen (from
0 to 479) and 640 pixels across the screen (0 to 639). However,
all row and column parameters you enter in your Gamebasic CALL's
must not be greater than 449 and 607 respectively.

This mode lets you create characters 32 pixels wide and 30 pixels
deep. The character's size will be about the same as those
created in screen mode 1, but it's definition will be much higher
(more pixels per inch..)

     The higher density of pixels on the screen and the more
pixels you can use to define your character will give you a much
better character definition than in screen mode 1.



     The following is an example of a char$() definition for
screen mode 2 characters:


char$(1, 1) = "                  66            "
char$(1, 2) = "                 6666           "
char$(1, 3) = "                6666666         "
char$(1, 4) = "              6668886666        "
char$(1, 5) = "               66888118888      "
char$(1, 6) = "               888888888 8      "
char$(1, 7) = "               888888444        "
char$(1, 8) = "                888888888       "
char$(1, 9)= "                888888           "
char$(1,10) = "            2222222222          "
char$(1,11) = "      888855555555555588888     "
char$(1,12) = "    8888855555555555555588888   "
char$(1,13) = "   888885555555555555555888     "
char$(1,14) = "  888885555555555555555588   88 "
char$(1,15) = " 558888555555555555558888  8888 "
char$(1,16) = "  555588888555555555888888888   "
char$(1,17) = "    555588888555555555888888    "
char$(1,18) = "      55555555555555555         "
char$(1,19) = "         888888   888888        "
char$(1,20) = "      888888           888888   "
char$(1,21) = "   888888             888888    "
char$(1,22) = "  888888             888888     "
char$(1,23) = " 888888             888888      "
char$(1,24) = "188111             888888       "
char$(1,25) = "111111       1888881            "
char$(1,26) = "  11111         11111           "
char$(1,27) = "    11111         1111          "
char$(1,28) = "                                "
char$(1,29) = "                                "
char$(1,30) = "                                "

     However, there is a trade-off (as there is with
everything!). If you are programming a fast action game, your
game's speed will be somewhat slower if you code it in screen
mode 2. If speed is not a critical factor in your game, use
screen mode 2 to get a better character definition.

     HINT:   When you program your game, set up two variables
called R ! and C ! (for row and column),  set them to a value of
1, and code your program in gb.screen mode 1.      When you
include row, column and tolerance parameters in GameBasic calls,
code them as 10*R !, 23*C !, etc... (assuming the first parameter
was for row 10 and the next was for column 23). Now, when you
want to try out how fast the game plays in screen mode 2, all you
need to do is change the value of R ! to be 2.4 and change C ! to
be 2, change gb.screen = 2 and run your program (your characters
will be much smaller until you recode them in the new
dimensions).

7.2. GB.SLOWDOWN
________________


     If you are lucky enough to be running your game on a very
fast computer (ie a 486 or better), you may find that it runs too
fast. If this is the case, then set the variable gb.slowdown to a
value of between 10 and 32,000 to slow the game down.


7.3. KEY REPEATAMATIC RATE.
___________________________

     If, when you hold down a key while you're playing your game,
there is an extra-long delay before the key-controlled sprite
moves, you may be able to reduce this delay by changing the
repeat and delay rate that DOS sets up when the system boots up.

   To do this, you will need to add the following command to your
AUTOEXEC.BAT file and restart your computer:

     MODE CON: RATE=20 DELAY=1

     Note that this may not be feasible if your terminal is on a
network.


7.4  SPLIT-SCREEN FEATURE.
__________________________

     With Gamebasic, you can program your game so that specific
sprites only move within certain screen boundaries.

     Set GameBasic variables gb.screen.start.row,
gb.screen.start.col, gb.screen.end.row  and gb.screen.end.col
to be the screen limits you want before creating the sprites that
should move within these limits.

     Any sprites you CREATE after these variables have been set
will then wrap, stay or bounce etc.. within these defined
limits.Using this feature, you could program a two-player game
where each player plays in his own "window" with his own
sprites....

     At any time in your game, you can change these variables and
create new sprites, with new screen limits, without affecting
previously-created sprites.


7.5  USING THE BASIC TIMER IN GAMEBASIC.
_________________________________________


     In some games that you develop in Gamebasic, you will want
to make something happen after a wait of a couple of seconds or
more (a period of time measured from a specific event). For
example, perhaps you don't want Aliens to fire fireballs until
the game has been played for 3 or 4 seconds. Maybe, in another
game, you might want to start a helicopter crossing the screen
after 1 minute of play. To do this, you will use the Basic TIMER
command.

     Here's how it works. At the point in your program where you
want time to be measured from, (maybe just before the game goes
into the main program loop?) include an instruction like the
following:

     time.start! = TIMER

     TIMER is a Basic instruction that returns the number of
seconds from midnight to the time in the computer's internal
clock at the time the instruction was issued. This is quite a
large value, so we have to tell Basic to set up a large variable
to contain it - this is what the ! character after the variable
named time.start means. If you don't include the ! character,
you'll get an error message from Basic when it runs.

     Next, at the place in our program where we want to start
something happening after a number of seconds or minutes have
elapsed, include something like the instructions following the
CALL MOVE statement:

          time.start! = TIMER
          DO WHILE end.of.game$ = "n"
               CALL MOVE
               time.now! = TIMER
               IF time.now! - time.start! > 180 THEN
                    time.start! = time.now!
                    CALL CREATE (.. .. .. )
                    .         (logic to start our special action
                    .         happening...)
               ENDIF

     The example above will wait until 180 seconds (or 3 minutes,
for those of you not too mathematically inclined) have passed
since we went into the main program loop before it executes the
CALL CREATE logic to start our special action.
     Notice that once we get into this logic, we reset the
variable time.start! to be equal to time.now! (the time that we
started our special logic). This would then reactivate our
special action code when another 3 minutes have passed. Clever,
huh? By the way, seconds can be a decimal value, so if your
instruction above said

 IF time.now! - time.start! > 0.5 THEN .....

then your special action would happen 1/2 a second after the main
program loop was entered.

               APPENDIX A - INKEY Values
Key                  Value       Key              Value
_________________________________________________________

Esc                       27         Y               121
F1                        59         U               117
F2                        60         I               105
F3                        61         O               111
F4                        62         P               112
F5                        63         {               123
F6                        64         }               125
F7                        65         [                91
F8                        66         ]                93
F9                        67         A                97
F10                       68         S               115
F11                      133         D               100
F12                      134         F               102
~                        126         G               103
!                         33         H               104
@                         64         J               106
#                         35         K               107
$                         36         L               108
%                         37         Spacebar         32
^                         94         :                58
&                         38         "                34
*                         42         ;                59
(                         40         '                39
)                         41         Z               122
_                         95         X               120
+                         43         C                99
|                        124         V               118
BKSP                       8         B                98
`                         96         N               110
1                         49         M               109
2                         50         <                60
3                         51         >                62
4                         52         ?                63
5                         53         ,                44
6                         54         .                46
7                         55         /                47
8                         56         Insert           82
9                         57         Home             71
0                         48         Page Up          73
-                         45         Delete           83
=                         61         End              79
\                         92         Page Down        81
Tab                        9         Up Arrow         72
Q                        113         Left Arrow       75
W                        119         Down Arrow       80
E                        101         Right Arrow      77
R                        114         Grey +           43
T                        116         Grey -           45
CAUTION: THERE ARE DUPLICATE VALUES FOR KEYS F1 TO F6.
CALL ACTIVE             (sprite.no1,  sprite.no2,  return-value)
                         To find out how many sprites
                         are active between sprite
                         numbers 10 to 30:
                         CALL ACTIVE(10,30, number.active)

CALL CHANGECHAR          (sprite.no,  char.no)
                         To change sprite number 1's
                         character to character 2:
                         CALL CHANGECHAR (1, 2)

CALL CHECKHIT            (sprite.no,  target.sprite1,
                         target.sprite2, tolerance, return-value)
                         To find out if sprite number 1
                         has hit any sprites between 10 to 30,
                         with a tolerance of 8 pixels:
                         CALL CHECKHIT (1, 10, 30, 8,
                         sprite.number.hit)

CALL COLOUR              (Colour.code$,  colour.name$,  blue,
                         green,  red )
                         To change the background colour:
                         CALL COLOUR("0", "back",10,23,30)
                         To change the colour that text
                         is printed  (in PRINT command)
                         CALL COLOUR ("F", "text", 23, 45, 10)

CALL COLOURRESET         This subroutine has no variables.
                         To reset colours back to
                         original QBasic colours:
                         CALL COLOURRESET

CALL CONTROL     (sprite.no,  horiz$,  vert$,  pixspermove,
      "U", keyup,     charup,shootdirectup,    shootcharup,
      "D", keydown, chardown,shootdirectdown,shootchardown,
      "L", keyleft, charleft,shootdirectleft,shootcharleft,
      "R", keyright,charright,shootdirectright, shootcharright)
                Example of the CALL CONTROL statement used in the
                  Ducks In Space game:
                         CALL CONTROL(1, "Y", "Y",6,
                            "UP", 72, 8, 0, 3,
                            "DOWN", 80, 9, 180, 5,
                            "LEFT", 75, 10, 270, 6
                            "RIGHT", 77, 11, 90, 7)

CALL CREATE              (sprite.no, char.no, col, row, speed,
                                   pixspermove, direction,
                                   horiz$, vert$, track$)
                          To create sprite # 1 using
                          character #7, starting in col 20,
                          row 30 with a speed of 40 moving
                          straight up (0 degrees) at 5 pixels
                          each time and wrapping around the
                          screen:
                          CALL CREATE (1, 7, 20, 30, 40,
                                        5, 0, "W", "W", " ")

CALL DEFINECHAR           This subroutine needs no variables.

CALL DELETE               (sprite.no1, sprite.no2)
                          To delete sprite # 1:
                          CALL DELETE (1,0)
                          To delete sprite #'s 10 to 20:
                          CALL DELETE (10,20)

CALL DISTANCE             (sprite.no1, sprite.no2, distance )
                          To find out the distance
                          between sprite #1 and #10:
                          CALL DISTANCE (1, 10, dist)

CALL GETANGLE            (sprite.no1, sprite.no2, return-value)
                          To get the angle in degrees
                          between sprite # 1 and # 20:
                          CALL GETANGLE (1, 20, angle)

CALL INFO                 (sprite.no, col, row, speed,
                          direction, char.no, hit.edge$,
                          pixspermove)
                          To get information on sprite # 23:
                          CALL INFO (23, c, r, s, d,
                                  charno, hitedge$, ppm)

CALL MOTION               (sprite.no, speed, direction,
                                pixspermove)
                          To change only the direction of
                          sprite #6:
                          CALL MOTION (6, -1, -1, 5, -1)

CALL MOVE                 This subroutine needs no variables.

CALL MOVEBACK             (sprite.no)
                          To move sprite # 3 back to its
                          position prior to the last move:
                          CALL MOVEBACK (3)

CALL MUSIC                 (type$, length$, tempo$, octave$,
                                    notes$)
                          To play the notes ABCDEFG in
                          octave 2 for length 10
                          and tempo 200:
                          CALL MUSIC("S", "L10", "T200",
                                   "O2", "ABCDEFG")

CALL PAUSE                (number)
                          To pause program for 10
                          seconds:  CALL PAUSE (10)
                          To pause program until any key
                          is pressed: CALL PAUSE ( 0 )

CALL PIXELCOLOUR          (sprite.no, top.left, top.right,
                                 bottom.left,bottom.right)
                          To query the pixels at extreme
                          corners of sprite # 4:
                          CALL PIXELCOLOUR ( 4, tl, tr,
                                   bl, br )

CALL QUESTION             (Question.row, Question.col, Answer.row,
                          Answer.col, Question.no, Result$)
                          To display a question at row
                          10, column 30 and answer
                          at row 15, column 30:
                          CALL QUESTION (10, 30, 15, 30,
                          quest.no, right.or.wrong$)

 CALL RAND                (rand1, rand2, return-value)
                          To get a random number between
                          1 and 10:
                          CALL RAND (1, 10, rand.num)

CALL SHOOT                (sprite.no, charno, from.spriteno,
                             to.spriteno, speed, pixspermove, horiz$,
                             vert$)
                           To create sprite # 12 as a
                           missile (character # 40) to be shot
                           from sprite #3 to sprite #40 at a
                           speed of 35 and 6
                           pixelspermove, and for the missile
                           to get deleted at any screen
                           border:
                           CALL SHOOT (12, 40, 3, 40,
                                             35, 6, "D", "D")

CALL TEXTSCREEN            (screen.mode, clear.screen$, choice$)
                           To print "Want to play again?
                           Y/N : " in screen mode 2 at row 20,
                           column 10 without deleting the
                           screen:
                           gb.line$(20) = "Want to play again? Y/N : "
                           choice$ = "YN"
                           CALL TEXTSCREEN ( 2, "N",choice$)
                           IF choice$ = "Y" THEN . .
                            . . .

CALL TRACK                 (Row.or.Col$, start.row.or.col.no,
                                 start.no, end.no, width, track$)
                           To write a row track using
                           track C to the screen at row 10,
                           starting in column 30, ending in column
                           300 for 2 pixels wide:
                           CALL TRACK ("R", 10, 30, 300, 2, "C")

F 1  :         TOPIC HELP
               Provides help screens on the QBasic command
               which the cursor is under.

F 3 :          REPEAT FIND
               If you use the Alt + S(earch) + F(ind) feature of
               QBasic to find all occurrences in your program of
               a specific character string, then the F3 key will
               find the next occurrence.

F4 :           OUTPUT SCREEN.
               Toggle between the program edit screen and the
               output screen.

Shift + F5     RUN PROGRAM
               Run program from start.

F5 :           CONTINUE PROGRAM
               If you have paused the program with an F9
               breakpoint or pressed CTRL-Break, you can start
               the program running again from the place it
               stopped by pressing F5.

F6 :           IMMEDIATE WINDOW.
               QBasic provides a window at the bottom of the
               program edit screen into which you can code QBasic
               commands. You toggle in and out of this window by
               pressing F6. For example, if you were debugging
               your program and had it paused and wanted to see
               what was in a particular variable you could press
               F6 to access the Immediate window, then enter
               LOCATE 10,20 : PRINT variable.name , then flip to
               the output screen using the F4 key to see what was
               printed.  You can also change the contents of your
               program's variables while the program is paused
               using this feature. However, since there is a high
               possibility that the screen output you create
               through this immediate window will upset the
               position of your sprites on the screen, use this
               feature with caution.

F8 :           INSTRUCTION STEP  While debugging your program, do the
               next highlighted instruction only.

F9 :           TOGGLE BREAKPOINT.
               In the program edit screen, set a breakpoint on
               the current line. If one is already set, pressing
               F9 will turn it off.

F10 :          Like F8, but if the highlighted instruction is a
               CALL xxxxxx or GOSUB, Basic will process all code
               in the procedure before it breaks again.



